Redesign Redux

Time:2020-12-2

Redux is hard to learn? Is it tedious to write code?
Let’s take a look at rematch’s thinking and simplification of redux~

Original text: redesigning Redux, Shawn McKay

After all these years, shouldn’t the problem of state management be solved long ago?
Intuitively, developers seem to recognize the unspoken rule that state management issues seem to be more complex than they think. In this article, we will discuss the problems you may have encountered:

  • Do we really need a state management library?
  • Is Redux really popular? Why?
  • Can we propose a better state management scheme? If so, how?

Do you really need a state management library?

Front end development is not just about moving pixels left and right. The real art of development is to master how to manage the state.
The simple and crude answer is: state management is complex, but not so complex.

Take a component-based view framework / library as an example, such as react. Let’s see what options we have:

Redesign Redux

1. Component status

A state that exists within a single component. In react, it means to usesetStateTo updatestate

2. Related status

The state passed from the parent component to the child component. In react, it is passed to the child component through the attributeprops

3. Supply status

Save in rootProviderIn the component treeconsumerStatus of. In react, corresponding tocontext API

Most of the state exists in the view because it is used to reflect the user interface. So, who are the other states that reflect the underlying data and logic?

If you cram all the states into the view, it is a serious violationSeparation of concerns。 It will bind you firmly to a JS view library, making the code difficult to test. What’s more, it may cause you a lot of trouble because you have to constantly think about and adjust where your state is stored.

State management becomes more complex due to changes in architecture design, and it is often difficult to determine which components need which states. The simplest approach is to include all States on the root component. If you do, it’s better to choose the next way.

4. External state

State can be moved out of the view library, and then can be usedProvider / consumer modelPut the state backconnectLook back at the gallery.

Redux is perhaps the most popular state management library. It has gained huge popularity in the past two years. So why does a simple library get so much attention?

Is it because of its higher performance? Not really. In fact, it slows down every callback that has to be processed.

Is that because it’s simpler? Also decided not to.

In simple terms, then pure JS is. As TJ said:

Redesign Redux

Why don’t you use it directlyglobal.state = {}What about it?

Why Redux

In essence, Redux and TJ are talking about the same thing, but Redux encapsulates some pipeline tools.

Redesign Redux

In Redux, we can’t change the state directly. The only way to change the state isdistribute(dispatch) oneaction(action) into the pipeline, the pipeline will automatically update the status according to the action.

As can be seen from the above figure, there are two sets of listeners in the pipeline:middleware (Middleware) andsubscribe(Subscription)。 Some middleware functions are used to monitor actions, such as logging, development tools and initiating service requests. Subscriptions are functions that broadcast state changes.

Finally, the synthesizer function is responsible for splitting state changes into smaller, more modular, and easier to manage code blocks.

Redux really simplifies the development process compared to using a global object.

To sum up, we can regard Redux as a global object, which not only provides hook before / after state update, but also can synthesize new state in a simple way.

Don’t you think Redux is too complicated?

It’s too complicated. In the normal development process, there are some undeniable signs that can be used to determine whether the framework API needs to be improved. These signs can be summed up in the following formula:

Redesign Redux

Among them,Time savedIs the time spent using the framework for development,Study timeIt’s the total time spent reading framework documents, learning tutorials, and mastering new concepts.

Redux itself is a compact library, but its learning curve is steep. Although many developers can overcome the difficulty of learning functional programming in depth and benefit a lot from Redux, many developers are reluctant to use jQuery again.

In jQuery, you don’t need to understand what “comonad” is or how to manage state through function composition.

The purpose of any framework or library should be to make complex things more simple.

Of course, I don’t mean to blame Dan Abramov, Redux’s author. Redux has become so popular in its early days that there is not enough time to elaborate.

  • How can we refactor a library that has been used by thousands of developers?
  • How can we reasonably launch a press conference that will affect numerous major changes of projects?

No one can. But we can provide better support, such as improving documentation, promoting video tutorials, and expanding the community. Dan Abramov did a great job in these areas.

Or there is another way to change the status quo.

Redesign Redux

In my opinion, it is necessary to rewrite redux. At least the following six aspects can be improved to be more friendly.

1. Initialization process

Let’s take a look at a basic Redux initialization process, as shown on the left side of the following figure:

Redesign Redux

A lot of developers stop at one step here, and they just don’t know. What is?chunkcomposeWhat the hell is that? Can a function still be used in this way?

If Redux is based on configuration rather than function combination, the initialization process like the one on the right looks more reasonable.

2. Simplified state synthesizer

The state synthesizer in Redux can use aswitchTo replace more than one unnecessaryswitch

Redesign Redux

If the state synthesizer is matched according to the type of action, then we can use reverse thinking to turn the synthesizer into an acceptancestateandactionA pure function with two parameters. Perhaps more simply, we can plan the actions and pass only the state and a data payload.

3. Use async / await instead of thunks

In Redux,ThunksThe most common approach is to create asynchronous actions. In many ways, this usage is more like that of a smart hacker than an official recommendation. Let’s look at it step by step

  1. An action is first distributed, but it is actually a function rather than the expected object
  2. The chunk middleware checks every action to see if it is a function
  3. If it is a function, the middleware calls the function, and thedispatchandgetStateThe method is passed in

Is it really necessary? Isn’t it a bad practice to recognize a simple action at run time as an object, function, or even promise?

Redesign Redux

Can’t we just use async / await, as shown on the right side of the figure above?

4. Two types of movements

If we think about it seriously, there are two types of movements:

  1. Synthesizer action: triggers the synthesizer and changes the state
  2. Effect action: triggers an asynchronous action. This may also be called a synthesizer action, but the asynchronous function doesn’t change any state directly.

Therefore, it is more useful to distinguish between these two types of actions, and it is not easy to confuse them with thunks.

5. It is no longer necessary to define action type variables

Why does our standard practice distinguish action generators from state synthesizers? Can you just use one of them? Will changing one affect the other?

In my opinion, the action generator and the state synthesizer are the two sides of a coin.

const ACTION_ONE = 'ACTION_ONE'It can be said to be a redundant product that separates the action generator from the state synthesizer. If we combine the two together, there won’t be so many files that export these types of strings.

6. Combiner

According to the usage mode, combine and group the concepts involved in Redux, and we can get the following simpler pattern.

Redesign Redux

In this mode, the state synthesizer can automatically determine the corresponding action generator. At this time, the state synthesizer can automatically become an action generator.

With a simple naming convention, the following behaviors become predictable:

  1. If the state synthesizer is namedincrementSo the type of action isincrement。 A better approach is to add a namespace:count/increment
  2. Every move passespayloadProperty to pass data.

Redesign Redux

In this case, forcount.incrementWe can automatically derive the action generator from the state synthesizer.

Good news: better Redux

The above power up is why we created rematch.

Redesign Redux

Rematch encapsulates Redux and provides a simpler API without losing any configurable features.

Redesign Redux

Here is a complete example:

Redesign Redux

I’ve been using rematch in a build environment for months. As a mouse, my experience is:

State management has never been so simple and efficient.

Redux should not be abandoned, and it should not be abandoned.
Redux should learn philosophy with less cost and less code.

Try rematch!
What if you fall in love with it if you’re not careful?

Recommended Today

Talking about Java collection

preface Most programming languages provide array to save objects, and array is one of the most important data structures. However, the length of the array has been defined during initialization, which is immutable and troublesome to use. Therefore, Java inJDK 1.2The collection framework is added to the version to save and manipulate objects. The container […]