The author is a front-end engineer with 5 years of development experience. I’ve been using Redux since I touched the front end, and I have some experience with Redux. Today I share a Tip with you 😌.

The Slowly bloated Redux Store

From appreciation to slowly abandon

There’s no question that Redux has made front-end development easy, otherwise there wouldn’t be as many people using it. When the project was first built, there were only one or two global states in Redux, and everything looked comfortable.

But, over time, the page became more complex. There is A state on page A that needs to be reused across multiple components.

A shuttle, a couple of copy-pastes put this state in the Redux Store. Snicker: Redux is great.

Soon, page B will also have state that needs to be shared by multiple components. Don’t think about it. Just shuttle it.

Page A, page B, and page C. H. ammodendron shuttle…

So Store looks like this.

It’s ugly, it’s sad, but it’s okay.

On a Monday morning, a new requirement comes in that page B can access and modify the data in Pagea.a1.a1a.

State => state.pagea.a1.a1a in page B, and then call the related action for modifying pageA. The requirements are perfectly implemented, but every time I look at this code, I feel uncomfortable. They are not only ugly (because the data link is long), but also awkward (because pageB accesses the data in pageA).

Maybe I didn’t use it right

Start to think about whether there’s a better way to do it. Start reorganizing the data and start tiling.

It’s not even elegant to organize stores by page, but rather by domain model, with all the data tiled.

I have to say, full tiling has some advantages, because the access path is shorter, and the state is only related to the domain model, not the page. Except for the naming trouble.

This is also the reason why DVA’s store has only one layer of Models. However, the actual situation is not ideal. Most of the time, a model has a lot of irrelevant states, such as the return value of a back-end interface.

Get to the root cause

To place the state in the Redux Store, take the following steps:

  1. Write the model and register it in the Store. Files registered to the store start to be lengthy and often have to resolve conflicts 😭.
  2. Accessing data in store requires constant state.A.B. If there is no type file, the link is long and prone to errors.
  3. Update a state call, dispatch(‘updateA_B’), where type is a string. Rematch solves this problem.

Imagine if instead of concentrating state in a store, it could only be stored at the module level. To access the data, you need only import the store exposed by the module, and to modify the data, you need only call the method exposed by the module. This module can be placed wherever it wants, not in the Redux Store directory.

Try a new tool, use-global-hook

Warehouse address: use-global-hook

Basic usage

You only need to create a new file to store the model.

import React from 'react'; import globalHook from 'use-global-hook'; const initialState = { counter: 0, }; const actions = { addToCounter: (store, amount) => { const newCounterValue = store.state.counter + amount; store.setState({ counter: newCounterValue }); }}; Export const useGlobal = globalHook(React, initialState, Actions);Copy the code

Then in components that need to reuse that state, you simply reference the model. import React from ‘react’;

import React from 'react';
import { useGlobal } from './useGlobal';

const App = () => {
  const [globalState, globalActions] = useGlobal();
  return (
    <div>
      <p>
        counter:
        {globalState.counter}
      </p>
      <button type="button" onClick={() => globalActions.addToCounter(1)}>
        +1 to global
      </button>
    </div>
  );
};

export default App;
Copy the code

Performance optimization through mapState

Reference: Official example

Simplify status updates with Immer

Reference: Official example

Handle multiple Model existing dependency updates by exposing getState

There is no official example, it is a personal summary. Start by adding an action to each model with the following code.

function getState(store) { return store.state; }
Copy the code

ModelB updates depend on the latest modelA values.

function useHandleAB() { const [stateA, { updateA, getState: getStateA }] = useModelA(); const [stateB, { updateB }] = useModelB(); return function handleAB(opts) { updateA(opts); UpdateB (getStateA(), opts); // Update modelB dependent values}; }Copy the code

conclusion

Redux’s centralized state management has the following disadvantages:

  1. There has always been a debate on the reducer organization mode, because the centralized management leads to the long Store.
  2. All states need to be registered and accessed from state.
  3. ActionType string exists.

Use-global-hook Stores the model at the module level. Its module position can be arbitrarily placed, more flexible. Omitted state registration and fetching, more brief. Its actions also exist in a normal way, which is more natural.