Design Overview
The store & the model
Readux aims to simplify state management by encouraging all state to be managed by a store which holds a single entity, which we call the model.
Generally, we try to normalize the data in the model, that is, to organise it in such a way, that everything is described just once. This is desirable because a single source of truth means data can't get out of sync - we can't have a user profile and the metadata associated a post show two different profile pictures for the same user - because everything there is to know about the user is described exactly once in our model.
Actions & Updating the model
The only way to update the model is to dispatch actions against the store.
An action is merely a keyword (e.g. :add-todo
) and some (optional) data.
The point is for the dispatched actions to describe what happened and have
the store contain the logic dictating what to do in response to those actions.
This way, we hope to encourage the separation of application logic from the
presentation.
The store needs some way to handle the actions, to deside how the model
should be changed to reflect an :add-todo
action. That's the job of
the reducer function.
The reducer takes two arguments, the old model (i.e. the state of our
entire application as of this moment) and the action, and from these
constructs a new model.
The only important requirement here is that the reducer is pure, that is,
given the same input, we must always get the same output.
Getting data from the model
It's possible to call store->model
on a store to get a (read-only) atom(1).
However, using that approach is bad for two reasons:
1) Every component is now aware of, and depends on how our model is structured right now.
2) We will quite possibly repeat and re-run code which transforms the raw data into a format suitable for our components.
In readux you're encouraged to use queries to extract data from the store and transform it into some format more suitable to for one or more reagent components. By writing these query functions, we solve (1) in that changing the structure of the store only requires rewriting our queries and (2) because each query should only be computed when necessary, more on that later.
Notes
1) Technically a reaction
- think of it as a atom that can do an arbitrary
calculation which is only re-done when the data it depends on changes
underneath it. Because we just return the model, it effectively works as
a read-only atom.