No-boilerplate global state management in React

  • “New developers have a problem with flux architecture and functional concepts… They should essentially be producing events that describe how the application changes instead of imperatively doing it themselves. This is vastly different than the more familiar MVC-esque patterns.”
  • “I found trying to manage a complex state tree in Redux very challenging and abandoned it early on for my app. I really struggled to understand what best practices are outside of simple to-do app examples. I just never really understood how to use Redux in a real-world app with a complex state.”
  • “It often feels tedious to do trivial state changes.”
  • “It takes junior developers some time to get their head around the magic of autoruns, reactions, etc. Debugging becomes harder when you have to step through MobX code in order get to your own.”
  • “It’s annoying that Redux does not handle asynchronous actions out of the box. You have to spend a day figuring out this basic and essential use case. You have to research thunks and sagas. Then, you still have to figure out how to tie them in with actions. It’s a lot to deal with and makes you wish for good old Promises.”
  • “For Redux, I dislike that it creates a side-effects vacuum, which has to be filled by a bunch of middlewares. There is a problem in that none of the middlewares out there are perfect.”
  • “Whenever I use Redux, I ask myself, ‘What on earth was I thinking?’ It overcomplicates everything. Some would argue that the benefit of Redux is that you can choose the features you need (immutable, reselect, sagas, etc.); but in the end, you’ll be adding all of these to every project anyway.”
  • “Redux requires a ton of files to establish a new reducer. A lot of the advantages in practice do not tend to be worth the disadvantages.”
  • “Redux has too much boilerplate, and I have to maintain all of it.”
  • “You really need to use decorators for MobX. The non-decorator syntax is not nice, and it’s a big dependency.” MobX currently weighs in at 47kB.
  • “Redux requires a ton of tedious code to do the most basic things: declare your action name in your action file, create a saga file, add it to your root sagas, create your action generator to call the saga, connect your component to Redux so it can access the store, write mapStateToProps which calls a selector, write your selector to get your user info out of the store, write a mapDispatchToProps so you can dispatch an action in your component, dispatch an action in your component’s componentDIdMount, add an action to handle the result of your network request, write a reducer that saves the user info to the store, add another action to handle an error, add another action to handle loading state, write selectors and reducers for the error and loading actions, call your selector in the render function of your component to get and display the data. Does that seem reasonable for a simple network request? Seems like a pile of hot garbage to me.” While I’m not as experienced with sagas, I will plug my methodology for handling API requests with redux thunk.
  • “Global state packages are very cumbersome and complex to set up. They violate the KISS principle — Keep It Simple, Stupid.”

Keep It Simple, Stupid 💋

An Intuitive Approach

My personal take on the matter is that global state management systems appear to be designed with global state management in mind, not React. They are designed so broadly that the intention is to be usable even outside of React projects. That’s not a bad thing, but it is unintuitive for junior developers who may already be overwhelmed by learning React.

No Boilerplate 🔩

Minimal Setup or Modification

When we strip a lot of the features of Redux or MobX that developers find unnecessary, tedious, or otherwise superfluous, there isn’t much boilerplate needed. Especially when we gear our package towards React itself and not on being a global state solution for the Internet as a whole.

React Hooks 🎣

“I’m sorry, is this 24 Oct. 2018? React Hooks are here now, and I never have to use a class component again!”

Reducers: Modern Staples of State Management 🔉

With Redux’s dependency on reducers and React 16.7’s introduction of useReducer, I simply couldn’t pretend that reducers aren’t a modern day implementation of state management. How do you manage a third party global state without the boilerplate of reducers?

Conclusion 🔚

This isn’t the documentation for reactn, so I won’t detail the bells and whistles. I do want to outline a system that I believe is significantly more intuitive to React developers, in hopes that it may inspire creativity that is targeted to React solutions. There is absolutely no reason a global state package should require so much boilerplate or add so much complexity to a project. All of the above takes up a whopping 8kB uncompressed, on par with redux itself, without the need for middlewares to handle asynchronous state change.

Senior front end engineer / charlesstover.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store