Goodbye Redux! I have a preferer immutable react state manager
Tags: state, react, redux, immutable
Published: 2020-09-09 02:10:20

---
title: Goodbye Redux! I have a preferer immutable react state manager
published: true
description: ReactImmut is a react state manager which provides immutable state manangement with very easy updating way.
tags: state, react, redux, immutable
cover_image: https://tsh.io/wp-content/uploads/2020/04/react-state-management-with-redux-and-hooks_.jpg
---

I have used react and react-redux for a long time. During last 2 years, I found it is so complex when I want to find out a single data flow from a dispatcher to usage through over than 5 files that I am now boring with redux's reducer and sync operation which makes async operation evil. I have been thinking about building my own react global state manager and finally I built a library *react-immut* to implement my goal.

## State data flow

In the ecology of react, we advocate one way data flow and immutable state circulation. In ideal, our state flow is like this:

![react state flow](https://dev-to-uploads.s3.amazonaws.com/i/emj78lld77d0w0jznzu8.png)

However, UX handler will push data back, so it comes to be a circle like this:

![react state circle flow](https://dev-to-uploads.s3.amazonaws.com/i/xbo1aw2e373p82dlwq51.png)

Each time we want to update a component's props, we will propagate the event back to the root parent to change the parent's state to trigger UI rerender. This make nested components full of no-use-pipe  props. 

To make it more convenient, react offical propose flux architecture which guide us to build global state manager. Redux (react-redux) become the most popular global state manager. The state data flow pattern switch to crossing components' level like this:

![redux store manager](https://dev-to-uploads.s3.amazonaws.com/i/z66h7rbij6uian1f40qo.png)

Global state manager make it much more clear in deep nested components net. Every 2 components no matter how many levels space are there between them, they can communicate with each other by two step with redux as a middleman.

## Evil Reducer

The time in which reducer was treated as a angel has past, along with code increasing, redux reducer and action functions make us headache. Why should I write so much non-real-related code? Our purposes is to finish UI building more quickly, but redux slow us down like a stumbling block. And when I debug, I have to jump amoung files to find out why the data has changed to make error. If you give me a knife, I will pass it to redux.

Let's look into what we will have in redux+react system:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/o25g048813w1mgqxrwmu.png)

Yes, we get one way data flow, but we have to code here, here and here...

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qkqo9mzl55p7gb1q41f9.png)

And I must combine these all parts together and must make them work well without any error.

**Too many parts cause fragility!**

In fact, I do want to focus on business components' dev.

## Diehard Immutable

To ensure my state change as immutable, I have grown to be a player of object-spread(...). Let's look into a case:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5ax73n6zuxdgi1520bxe.png)

Eumm... Why should I write so many ... and have to create such a deep nested repeated object?

## Magician Immer

[Immer](https://immerjs.github.io/immer/docs/introduction) is a library which help developers to immutablly modify object. It is amazing that it provides only one API `produce` function:

```js
import produce from 'immer'
```

And the typical usage is:

```js
const next = produce(prev, draft => {
  draft.root.parent.child[1].name = 'new name'
})
```

In the second parameter, it looks like a mutable operation, but in fact, it is just a draft, the output `next` is a new object which is from `prev`.

From now on, I will drop object-spread operation thanks for immer, easy, clear and magic.

## New Generation

React hooks is a new way to penetrate nested components net. React-redux has provided a `useSelector` hook function to get state from global store. `useContext` give us a chance to siphon from top context. `useReducer` is a sample plate for use to use `[state, dispatch]` pattern in local scope.

![Generation 2 global state management](https://dev-to-uploads.s3.amazonaws.com/i/qyl91e6dy0ku2lu7vem0.png)

Generation 2 global state management is based on hooks. You may hear the new state manager [Recoil](https://recoiljs.org/) which is published by a facebook team. In recoil, state and actions are abstract as atoms, selectors.

## Decent ReactImmut

I costed a weekend to finish a library `react-immut` which is a global state manager and has similar API as react-redux but without reducers. Let's look into a glance:

```js
import { createStore, Provider, useStore } from 'react-immut'

const store = createStore({
  name: 'tom',
  age: 10,
})

function App() {
  return (
    <Provider store={store}>
      <div class="container">
        <h3>Some Person</h3>
        <Person />
      </div>
    </Provider>
  )
}

function Person() {
  const [state, dispatch] = useStore()
  const { name, age } = state
  const grow = () => dispatch(state => {
    // here `state` is a draft of global state
    state.age ++
  })
  return (
    <div>
      <span>Name: {name}</span>
      <span>Age: {age} <button onClick={grow}>Grow</button></span>
    </div>
  )
}
```

Look, isn't is easy? We have no need to define reducers, and has a powerful `dispatch` which is based on immer and make state change clear, convenient and comfortable. 

This is a typical usage of react-immut, you can learn more from [repo](https://github.com/tangshuang/react-immut). *If you think this is cool, give me a star!*

## Summary

We have experienced crossing props state management, global middleman state management and now we are using hooks to manage our state (global or local). We have followed immutable (redux) and mutable (mobx) dispatching, and now we are facing mutable-produce-immutable dispatching. Which will you choose?