There are two ways of thinking of about UI: in terms of state or in terms of interactions.
This pattern is common in the Redux community. In this style of thinking, the building blocks of the app are reducers. Each reducer is tightly coupled to a specific part of the state. It decides how to respond to actions from the outside. It has full control over its part of the state, and that’s its only concern.
The main take away here is that state is the smart essence.
In this model, application state is represented as an inert tree.
The state tree is a combination of branches and leaves. A branch doesn’t hold any state itself but is a grouping of leaves that each hold chunks of the application state. For example, the branch state.entities groups the states of the posts leaf, comments leaf, etc.
When a user interacts with the UI, the application changes its state in response. As opposed to a reducers-based model, state is a passive data container here. And interactions are the ones in charge.
Let’s say a user manages his posts and removes one of them by clicking the “Delete” button. What’s happening under the hood? The state of this UI part is stored in the state.ui.postsList leaf. Clicking on the button, a user triggers an action creator and the app starts a request to the server. In response to this action, postId is added to the processingPosts set to show the spinner in the UI. It requires a change of the single ui.postsList leaf. Let’s describe it in the interaction module:
// Action creator: returns request action
// Action handler: reduces the state of the single leaf
Under the hood, redux-tree is an alternative version of Redux’s combineReducers, which makes it possible to represent changes to the state as a sequence of functions. This allows describing interactions in a very concise and consistent manner.
It’s super easy to integrate redux-tree into existing codebases as it supports classic reducers (so incremental adoption is absolutely possible) and it should be compatible with the most of the packages from Redux ecosystem. The main change it introduces is how Redux internally iterates over the reducers.
In the initial release of redux-tree, state is represented as an Immutable Record. We use Immutable a lot in our apps; it makes it easier to handle deep updates and prevent state mutations, Record allows access to properties using dot notation (as opposed to getters), and it’s possible to strongly type the state tree with flow. So, immutable-js is required (at least for now).