Introducing @react-state/store: A New State Management solution for React Applications

Vytautas Pranskunas
6 min readApr 4, 2019

--

Most of developers in front end world had been facing situations when not using state at all or using default state is not enough. However, every developer knows that it is difficult and might become nightmare when you need to track what, why and when was updated, especially in large applications.

In React world most popular state management libraries are Redux and MobX. In Angular it is @ngrx/store. I am a big fan of all of them because they gave me much inspiration, understanding and knowledge however, as a developer and solution architect I felt that there are too much boilerplate and there is a need for a different approach.

Birth of @react-state/store

Back in 2016 I started to work in company called CID. There I jumped on big data project where I met some really smart guys with some brilliant ideas about accessing and manipulating nested state peaces based on ImmutableJs and Cursors. We have built big data solution based on those ideas and it seemed to work blazing fast and reliable. It was simple to understand and build further even for new team members. (It was built on Angular 2+ to be honest 😃 During development I started to look around and investigating other state management solutions like Redux, MobX and @ngrx/store trying to figure out advantages and limitations.

After half a year I came up with idea of how to take best from all approaches and this how ng-state was born. Soon after I have ported into React because change detection and problems both worlds are solving are not so different 😎

What is @react-state/store

@react-state/store is state management library, built on top of RxJs which takes best from MobX and @ngrx/store — concept of streaming data to create observable data model and from Redux — immutable updates and store like single source of truth.

@react-state/store encourages simplicity, eliminates boilerplate, binds state to component but allows communication between not related ones. It has low learning curve (not counting ImmutableJs which adds a bit to learning curve but saves time and amount of bugs in the future).

Why to give it a chance?

Further in this post I will highlight some pros and cons of Redux and MobX which were kept in mind while developing @react-state/store.

Redux

GOOD THINGS

· Uses single store to store whole application state

· With a single store, it’s very easy to persist, hydrate, and read the state. Server rendering and data prefetching is trivial because there is just one data storage that needs to be filled and rehydrated on the client, and JSON can describe its contents without worrying about store’s ID or name.

· A single store makes time travel features possible

· Redux patterns force developers to think hard on the schema of the UI state tree.

· UI is simply the representation of the state tree

· Redux updates just those components that’s state has changed

THINGS THAT CAN BE BETTER

· Redux uses immutable states. But has price of learning curve especially for younger developer because you are not restricted of doing this:

// don't do this in Redux, because it mutates the array
function addAuthor(state, action) {
return state.authors.push(action.author);
}
// stay immutable and always return a new object
function addAuthor(state, action) {
return [ …state.authors, action.author ];
}

BAD THINGS

· Easy to end up in action hell when application grows — in the beginning it is all smooth and clear, but when application grows actions are being reused and chains of actions are created so it is very easy to lose track / debug who, when and why updated the state. In other words it easy to lost in application flow. You also need to think how to avoid actions clashing and introduce some lexical scopes…

· In Redux the data is usually normalized — that means that usually when we get nested object from API we need to flatten it and connect with ids. When sending it back we need to connect it back again. It creates unnecessary complexity and adds limitations. In some cases, you also might think that maybe API returns to much but that is also direct impact on backed team especially if you are not using GraphQL. Also think for yourself if I need to represent author and his posts in one smart component who state might look like:

{
author: {
id: 'b',
name: 'some author',
posts: [
{ id: 'a', name: 'post a' }
...
],
...
}
}

why should I normalize it to (not every one are doing this but this is considered as a best practice):

{
post: {
id: 'a',
authorId: 'b',
name: 'post a',
...
},
author: {
id: 'b',
name: 'some author',
postIds: ['a', ...],
...
}
}

btw — I am not sure why this is called normalization because for me data that comes from API is normal and only Redux needs it differently so I would call it rather de-normalization :)

· Adds much boilerplate — data normalization, actions, reducers, dispatchers

· Decouples state from component — in some cases it is good when couple components sharing state, but more often most of components just representing and mutating their peace of state and only fever needs display data from other state or trigger actions on other components. On one hand maybe we do not need to use Redux at all and React state would be enough but on the other how to not fall into mess when number of components that talks to each other grows?

· It is not easy to structure code to not end up with huge reducers

· Learning curve — many developers found themselves lost in the Redux world of strange terms, weird entities and the connection between them: thunk, selectors, reducers, actions, middlewares, mapStateToProps, mapDispatchToProps, etc’. Learning all this stuff is not easy, and combining all of this together correctly takes time and practice.

MobX

GOOD THINGS

1) A lot less mental overhead (no need to normalize state, no reducers, no actions, no optimizing mapStateToProps, no connected components)

2) Developer velocity and productivity. You can very quickly put together decent sized applications with Mobx and the code also scales well within the large teams.

DOUBT-ABLE ADVANTAGES

1) Can have multiple stores — from my perspective it is needed rarely e.g. if you have performance problems with updating lists of thousands of items that are on screen at the same time many times per second

But in this case you might ask questions like:

· do I really need such amount of data — because it is costly?

· how DOM will handle it? Will it still be user friendly and responsive?

· how mobile will handle it?

BAD THINGS

1) Mutable (impure) state

2) Magic behind MobX update logic — You don’t see as much of when and how your data is being updated, and it may be harder to track through the application

If you enjoy the article, give some claps to motivate ✋✋✋

Follow me on twitter @VPranskunas 👍

Conclusion

If mentioned above does makes sense to you and you feel the same go and try @react-state/store.

Here is complete working application

You can find out more in docs:

and can install it from npm:

In future posts I am going to explain how to build application from scratch. Also I am going to cover ng-state built for Angular applications.

--

--