Comparing Redux, MobX & setState in React

First published in Zalando Tech Blog.

Special thanks to Eugen Kiss for revising this post.

Introduction

React is a declarative, efficient, and flexible JavaScript library for building user interfaces. Compared to other frontend libraries and frameworks, React’s core concept is simple but powerful: ‘React makes it painless to design simple views and renders by using virtual DOM’. However, I don’t want to go into detail about virtual DOM here. Rather, I want to show three ways how you can manage state in React. This post requires basic understanding about the following state management approaches. If not, check out the following documents first.

setState: React itself ships with built-in state management in the form of a component’s `setState` method, which will queue a render operation. For more infos => reactjs.org MobX: This is a simple and scalable library applying tested functional reactive programming (TFRP), which stands for: ‘Anything that can be derived from the application state, should be derived. Automatically.’ For more infos => mobx.js.org Redux: Maybe the most popular state management solution for React. The core concepts are having a single source of truth, immutable state and that state transitions are initiated by dispatching actions and applied with pure functions (reducers). For more infos => redux.js.org

Location

setState is used locally in the component itself. If multiple children need to access a parent’s local state, the data can either be passed from the state down as props or, with less piping, using React 16’s new Context API. MobX can be located in the component itself (local) or in a store (global). So depending on the use case the best approach can be used. Redux is providing the state globally. Means the state of the whole application is stored in an object tree within a single store.

Synchronicity

setState is asynchronous.* MobX is synchronous. Redux is synchronous.

*Why asynchronous? Because delaying reconciliation in order to batch updates can be beneficial. However, it can also cause problems when, e.g., the new state doesn’t differ from the previous one. It makes it generally harder to debug issues. For more details, check out the pros and cons.

Subscription

setState is implicit, because it directly affects the state of the component. Changing the state of child components can be done via passing props (or Context API in React 16). MobX is implicit, because it is similar to setState with direct mutation. Also component re-renders are derived via run-time usage of observables. To achieve more explicitness/observability, actions can (and generally should) be used to change state. Redux is explicit, because a state represents a snapshot of the whole application state at a point in time. It is easy to inspect as it is a plain old object. State transformations are explicitly labeled/performed with actions.

Mutability*

setState is mutable because the state can be changed by it. MobX is mutable, because actions can change the state of the component. Redux is immutable, because state can’t be changed. Changes are made with pure functions which are transforming the state tree.

* With mutability the state can be changed directly, so the new state overrides the previous one. Immutability is protecting the state from changes and (in Redux) instead of directly changing the state it dispatches actions to transform the state tree into a new version.

Data structure

setState - MobX Graph: multidirectional ways; loops can be used. The state stays denormalized and nested. Redux Tree: is a special kind of graph, which has only one way: from parent to child. The state is normalized like in a database. The entities only reference to each other by identifiers or keys.

Observing Changes

setState - MobX: Reactions are not producing new values, instead they produce side effects and can change the state. Redux: An Object describes what happened (which action was emit).

Conclusion

Before starting to write your application you should think about which problem you want to solve. Do you really need an extra library for state management or is React’s built-in setState fulfilling your needs? Depending on the complexity you should extend it. If you love to go for the mutable way and expect the bindings automatically, then MobX can fit your needs. If you want to have a single source of truth (storing state in an object tree within a single store) and keep states immutable, then Redux can be the more suitable solution.

Hopefully this post gave you a brief overview about the different ways to manage state in React. Before you start with one of those libraries, I recommend to go through the docs of each. There are a lot more treasures to discover!

TL;TR:

This post is inspired by: