⚛ The React State Museum

May 07, 2018 0 Comments

⚛ The React State Museum



This is to serve as a Rosetta Stone of state management systems. A basic packing list app was built in:

Surely you’re familiar with one or more of the aforementioned systems, and now you can leverage that knowledge to better understand many others. It’s your chance to see what all the buzz is about, and honestly, how similar all these state systems really are.

To portray these systems in a terse and understandable form, the chosen app is a simple packing list app with only the ability to add and clear.

Simple as it gets app (Native and Web)

To illustrate state jumping the wire, the ADD/CLEAR is one component, and the LIST is a secondary component in all examples.

Even the two main components (adding/listing) have been abstracted to an imported library, leaving only fundamental code in order to emphasize state choice(s). The code is meant to be minimalistic.

The code for each of these systems can be found in React and React Native.


Use the above repo to personally dive into each of those systems and check them out! 🔥

If you want code, check the GitHub, if you want opinions, continue into this very long description below.

Here I jump into the differences between each item in the museum, and that which makes it unique. If you’ve got some strong opinions, or experiences, please share them in the comments. I’m also interested in giving this report as a fun-filled conference talk.

Here’s the most basic structure of state management, it depends only on the fundamental understanding of components and their encapsulation. In many ways, this is a great example for beginners in React. Explicitly raising state to a root component that all components are children of identifies the props vs. state relationship. As an application grows, explicit connections down into components would be more and more complex and fragile, which is why this is not commonly used.

The Code: React | React Native


There’s been a lot of buzz about the updates to Context. In fact, the final form of Context in 16.x feels a bit like a state management system itself. For simplicity, the context allows for provider and a consumer. All children of a provider will have access to the values applied there. All non-children will see the context defaults. The following graph explains such lineage.

Only children inherit

On a second, and very opinionated note, I’m not a fan of the consumption syntax structure. Clearly, it’s a function that is the child of Consumer, but it feels like it violates JSX while mega-overloading all use cases of braces.

A pedantic issue, but the readability of code should always factor into API, and on this front, Context starts to feel a bit dirty.

The Code: React | React Native


I’ll dare say at the time of this writing Redux is the most popular state management tool, and therefore the most attacked. Writing a solution in Redux took many files, and almost double the lines of code. But to Redux’s defense, it’s simple and flexible.

If you’re unfamiliar with Redux, it’s a functional approach to state management that provides time-travel and clean state management in a form like a reducer function. Dan Abramov’s video explaining redux has been watched many times.

In short, it’s like having someone shout commands in your app (Actions) which are projected via Action Creators. Data managers in your app (Reducers) hear those shouts, and can optionally act on them. I love my pirate ship analogy, so shouting “MAN_OVERBOARD” can tell your crew counter to subtract the staff by one, the accountant to re-split the treasure, and the guy swabbing the deck can just ignore it because he doesn’t care.

I like this analogy, because shouting is a powerful way to manage all corners of your app, and in larger applications, noisy. Combine this with no way to handle side-effects and the need to glue on an immutable structure to make it all work, Redux is the bill-by-hour developer’s friend.

The Code: React | React Native


MobX is one of the EASIEST state managers to get started with. Open the readme, and follow along and you’ll have things running in no time. It feels like mutable JS, and it really kind of is. The only part that might throw you for a loop is the decorators like @observer on classes. Though odd, they kind of clean up the code a bit.

@observer is like an automatic mapStateToProps + reselect if you’re used redux things — Steve Kellock

Be sure to checkout Nader’s blog post highlighting some more advanced topics on switching to MobX.

In summation, MobX was one of the smallest and simplest tools to add!

The Code: React | React Native


Unstated was as easy as MobX. Much like MobX felt like mutable JavaScript, Unstated felt like adding more React code. I actually feel that Unstated feels more like React than Context did.

It’s simple, you create a container, and inside that container, you manage state. Simple known functions like setState exist inside the state container. It’s not just an apt name; it’s an apt React based manager.

I’m not sure how well it scales or handles middleware etc. but if you’re a beginner to state management MobX and Unstated are the simplest tools to get up and running!

The Code: React | React Native


Yes, this is VERY different from vanilla MobX. It’s a common misconception.

Even my co-workers try to shorten the title down to “MobX,” and I’m always pushing MST as an alternative instead. With that being said, it’s important to note MobX-State-Tree sports all the great features of Redux + reselect + Side-effect management and more all in one opinionated bundle with less code.

In this small example, the only thing that’s obvious is the terse syntax. The lines of code are barely bigger than our original MobX example. Both share that succinct decorator syntax. Though it takes a bit of time to really get all the benefits out of MobX-State-Tree.

The most important note is that if you came from ActiveRecord or some other kind of ORM, MobX-State-Tree feels like a clean data model with normalized relations. This is a great state management tool for an application that will scale.

The Code: React | React Native


If you haven’t jumped on the GraphQL train, you’re missing out. Apollo GraphQL + AppSync is a great way to manage your state, AND handle offline, AND handle fetching API, AND handle setting up a GraphQL server. It’s a serious solution. Many have projected GraphQL to effectively “solve” the state debate. In a lot of ways that’s easy, and in a lot of ways, that’s hard.

Not everyone is ready to use a GraphQL server, but if you are, then AppSync is an easy way to handle all your data in your DynamoDB. It takes more time/energy to get this up and running, but with clear benefits.

In my example, I don’t really use all the bells and whistles. You can see the delay as the data awaits from the server, and I’m not using subscriptions to get updates. This example could get better. But it’s as simple as wrapping the config with the components. Tadaaaaa! The rest is history.

Special note: Please be careful what you put in the packing list in this example, as it’s shared.

The Code: React | React Native


This is a strange one in the group. In many ways, you’re wondering how setState is involved, and the answer is simple. The idea of breaking state down into a state-machine is very different from most state management systems.

By creating an xstate machine config, you handle how state gets passed, called, and identified. Therefore, you must identify ALL states your app can be in, and ALL ways it can move from one state to another. Much like dispatching an action in Redux, you have to transition to another state on a given event.

It’s not a full state management system; it’s merely a state-machine for your state management.

Here’s the chart created by our statechart

Exciting benefits come from using statecharts. Firstly, you can be protected from transitions you don’t want. For instance, you can’t transition to “loaded” state without first typing text. This stops empty adds to our packing list.

Secondly, all transitions of state can be automatically generated and tested. With one simple command, multiple snapshots of state are generated.

CAVEAT: On React Native I had to yarn add path to satisfy some unused import in a dependency. This was a sneaky gotcha for native only

The Code: React | React Native


Of course, we’ll feature the awesome work of Formidable Labs. Freactal is a very advanced example and states it can replace redux, MobX, reselect, redux-loop, redux-thunk, redux-saga and more.

Though this was probably the most difficult one for me to setup, I still see it has great value. More examples would have helped. Special thanks to Ken Wheeler who agreed to answer any questions I had while reading through the docs.

The final code is succinct and straightforward. It feels a bit like the Context syntax in the end. I especially like the use of name-spacing effects separately from state, and computer though there’s not much stopping you from taking this convention to other libs.

The Code: React | React Native


ReduxX, while probably having a bit of trouble in SEO, is still a pretty cool name.

“Why is it you can add X to something to make it cool?”
— Gant X

ReduxX reads pretty well as in some ways it reminds me a bit of the charisma from Unstated, as we’re using react-styled verbiage to set and mutate state. One aspect that might seem alien, is the state is retrieved with getState as a function. This feels a bit like keychain access, and I wonder if there could be some certs/crypto mixed in easily? Food for thought. I see there’s obscureStateKeys: true which will swap keys out for GUIDs. Security-wise this library might have some interesting advantages.

As for how to use it, Set and Get via keys. That’s it! If you’re not worried about middleware, and you’re familiar with keychain globals, you already know ReduxX.

Special thanks to the author Mikey Stecky-Efantis for providing this example!

I’m sure there are other state managers out there which are being sorely under-represented here, and if you know them, please send a PR to the public repo. I’ll happily accept contributions so that we can all benefit. I’ll even update this blog post as new systems are added. So please, file tickets, and more importantly contribute! The museum thanks you 😆

Tag cloud