State Management at Scale: Redux vs. MobX

Once a Single-Page-Application (SPA) gets really big, good state management is needed. The state comprises all the data that the individual components of the SPA access. The individual components are sometimes simple components for displaying state data. This is relatively simple, but they must be automatically changed by the browser as soon as the data base changes. This means that state management must take care of a change impulse and ensure an update. More difficult for state management is enabling components to make changes. In addition to simple state changes such as through TextInputs, there are also asynchronous requests. Added to this is good testability and maintainability, as well as logging and debugging capabilities. All quite high requirements that can be handled by Redux or MobX in React and Vue.js. We’ve put both under the microscope and present our results here.
Redux – The Industry Standard
Redux is mainly preferred by the broad React community. That’s probably also the reason why Vue pardon vuex is also quite well known. Overall, Redux is more than twice as well known as MobX when comparing stars on GitHub.
Redux perfectly implements the Flux architecture (https://github.com/facebook/flux/tree/master/examples/flux-concepts). It describes a data flow that only knows one direction. Unlike two-way binding, which Angular uses for example, with Flux the data can only change indirectly through a triggered action via the dispatcher. As soon as the store receives an action, it can adjust its data base and pass it on to the view or components. The view can now trigger actions again, creating a cycle.
In the following code snippet, we show an action that is triggered, for example, by a button to add a todo to a todo list:
This action is now received by a so-called reducer, which returns the next store (here: state):
Additionally, some implementation effort is still needed so that the React or Vue components can actually use the addTodo action. Also, the todos must be connected to the state so that another component can display them and update when changed. The detailed example is available here: https://redux.js.org/basics/exampletodolist
Just quickly implementing a todo list with Redux turns into considerable effort. However, the Flux architecture offers a very good overview of the data flow. For very large projects, the higher effort pays off, as you can trace (central) changes to the state very well. Another huge advantage is the representation of the state as serializable JSON. The reducer produces a new JSON object after each change, which can be easily logged or stored in browser storage. For the latter, there’s redux-persist, which besides saving and restoring the state also handles migrations during version changes.
MobX – Cooler but Less Functionality
MobX is easier to understand and has significantly less overhead. While Redux implements the Flux pattern, MobX implements the Observer pattern. Another big difference from Redux is that the state is not an immutable JSON object, but the state is a singleton that can be changed directly. However, MobX also allows multiple states.
In the following snippet, for example, the TodoStore is shown:
The functionality can already be recognized just by the annotations. @observable marks the data to be observed. A component in React or Vue just needs to add the @observer annotation and the observer pattern is complete. However, the “big magic” is also the big disadvantage, as unlike Flux you lose track faster. What’s really nice about MobX, however, is the object-oriented approach and the little overhead through annotations. If you need more functionality, you should check out mobx-state-tree. This extension offers interfaces for middlewares, snapshots, and much more. But in my opinion, it doesn’t match the scope of Redux.
Conclusion
At innFactory, we have implemented most projects with Redux. The many addons and especially redux-persist make up for the rather annoying overhead. The somewhat higher entry barrier is caught by the team’s experience. Our in-house boilerplate has proven very helpful and is welcome to be used for new projects. We use it as a base for two productive projects: https://github.com/innFactory/create-react-app-material-typescript-redux

Anton Spöck
