The column has been off the platform for some time, but in these months, the discussion about technology in the team has not stopped. This article is a series of technology sharing promoted by a student in the group a few months ago. The cause of the topic was a “pleasant discussion” on the pros and cons of using Redux in the current project at the weekly meeting, which then resulted in a Spike on the current mainstream state management library of React. Now that the discussion is over, I’ll cut through this and the next few articles to talk about React state management practices.

1. Why is state management needed?

Before we discuss the pros and cons of a specific state management library, let’s take a look at this question: Why do you need state management when using React?

Here’s Kent C. Dodds’ Application State Management with React [1]. React is a component library of built-in state. Component can easily create and manage its own internal state and pass state externally through props. However, as the complexity of the project increases, the transmission of props becomes more and more complex, that is, the problem of Prop Drilling[2] appears:

Prop Drilling is the process by which you pass data from one part of the React Component tree to another by going through other parts that do not need the data but only help in passing it around.

In short, Prop Drilling refers to the behavior when a component does not need the Prop itself, but has to pass the Prop in order to enable its sub-components to obtain the Prop.

So, is Prop Drilling good or bad?

  • Advantages: Explicit is better than implicit

Prop Drilling avoids data model chaos caused by overuse of global variables to a certain extent through explicit passing. Global definitions make variables hard to track, so when we want to update or delete a variable, it is difficult to determine whether it is being used or not, and rash changes are likely to affect an unintended component.

  • Cons: Difficult to refactor

As the complexity of a project increases, it is common for a prop to be passed through multiple application scenarios at multiple component levels, so the length of code traceability increases, which makes it extremely difficult to analyze the performance of components, especially during code refactoring. The accumulated negative effects can become a big obstacle.

One of the main reasons for the existence of state management is to solve the Prop Drilling problem.

React provides some solutions to handle Prop Drilling, such as the Context API and Component Composition, but Redux is still one of the most popular state management libraries. Through a complete set of global store management solutions, it helps developers cope with the pain points caused by Prop Drilling.

2. What are the problems with using Redux?

Global definition store chaos

In practice, small projects that have just introduced Redux, as well as large projects with multiple teams, face the same problem: how to come up with a clear strategy for what data should be shared across the global store and what data should be avoided. For example, our front-end team had a time when the dominant philosophy was to get the right flow of data, so we put all the states in the Redux Store. In this implementation, Redux became an architecture-level hierarchy in our project for transferring data to the UI. However, this actually contradicts recommendation 3 in the Redux document [3] :

Here are some suggestions on when it makes sense to use Redux

1. You have reasonable amounts of data changing over time 

 2. You need a single source of truth for your state

3. You find that keeping all your state in a top-level component is no longer sufficient

This problem is not uncommon, take the management of Modal states as an example: In a parent page, there are two swappable child Tab pages, and in both of these child Tab pages, there is a button that invokes Edit Modal in the same style. Therefore, it is logical to reuse This Edit Modal, but if you manage the props of Modal in the parent page component, the implementation is more complicated. However, handing it over to Redux is a bit overkill, requiring unnecessary code for every simple change to Modal state.

On the other hand, as the number of pages in the project increases, so does the number of data models required to display it, the increase in unrestricted state inevitably leads to a deeper and harder to maintain structure of the global Store tree. After many twists and turns, developers can’t even be sure that a store defined a few weeks ago is still functioning as it was originally defined.

Component reuse difficulty

Redux is a typical non-fractal architecture [4] state library.

A unidirectional architecture is said to be fractal if subcomponents are structured in the same way as the whole is.

In a typing architecture, each subcomponent can be used as an application with the same structure. In Redux, the implementation relies entirely on the global Store at the top of the component tree, detached from the component. And the management of state is connected to the component, so the component without the Redux Store cannot run as a complete application.

Lack of side effects management

One theory is that Redux is designed to have no side effects, but in real life development, with today’s increasingly complex single-page applications, side effects still need to be dealt with.

Redux didn’t officially provide a solution for dealing with side effects, but the middleware mechanism was released, and with the advent of great middleware in the community like Redux-Thunk, Redux-Promise, and Redux-Saga, the problem was almost solved.

Too much template code

A seemingly simple application change will have to change multiple files to complete it. The benefit of template code can be explained as “the clarity and rigor of the code structure”. But as a downside, trying to make changes on such a fragmented, interconnected basis can be a real headache for developers. At the same time, too much template code can lead to more complex data flow, and the Redux Toolkit was created in part to solve this problem.

3. What’s the alternative?

There are many options for implementing state management in React besides Redux. Here are a few examples:

  • Independent state management library: This type of solution focuses on the implementation of state management, and implements a complete solution to completely take over React state management, such as Mobx and Recoil

  • The only thing that is missing is how to easily share state and logic, such as: constate, unstated-next

In the next article, we will combine the implementation ideas of the above libraries and analyze them from the following aspects:

  • Whether it can meet the most basic requirements of a state management library:
  1. Shared state

  2. Asynchronous processing

  • Whether there are improvements for existing pain points:
  1. Finer grained local state management

  2. Less template code

  3. Good TS support

References:

[1] Application State Management with React – Kent C. Dodds

[2] Prop Drilling – Kent C. Dodds

[3] Should You Use Redux? – Getting Started with Redux

[4] Unidirectional User Interface Architectures – André Staltz

“Zhuopai front-end work, focus on practical front-end technology, make programming more interesting!” Front-end technology of @ xian zhuo send NEXT Trucking – pull hook | Boss | zhihu Denver | | Jane books If you have any help for you to feel this article, quick to pay close attention to us!