Why doesn't React-setState update component state synchronously

Let's think the other way around. If setState is changed to a synchronous update state, what would React look like.

Suppose, we now have the opportunity to make a major design adjustment to React, set the function of setState to synchronously change this.state, that is, when the setState function returns, this.state has reflected the state change.

Then there are two design issues directly in front of us.

 

  1. Do you want to trigger an update process after setState updates the state?
  2. How to trigger the update process?


We have three choice answers to these two questions.

  1. setState automatically triggers the synchronized component update process;
  2. setState automatically triggers the asynchronous component update process;
  3. Simply, setState does not trigger the component update process at all, allowing developers to display the driver update process.

 

Let's take a look at the various options one by one to see if they work, what are the pros and cons.

The first option: setState automatically triggers the synchronized component update process

If so, that is, when the setState call returns, a complete update process has been completed, such a design should not work, because each setState will cause a component update is too wasteful!

The component update process triggered by setState includes four life cycle functions.

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

Each setState call goes through a circle of life cycle. Even if you think about it, it will cause performance problems. In fact, these four functions are pure functions, and the performance should be good, but the results returned by the render function will be taken. Doing Virtual DOM comparison and updating the DOM tree is time-consuming.

At present, React will put the effect of setState in the queue, accumulating a triggering update process, in order to minimize Virtual DOM and DOM tree operations to improve performance.

Well, we take a step back, when we are confident in the performance of React and today's CPUs and browsers, and don't care about this performance loss, but this design is still a problem.

The parameters of a shouldComponentUpdate function are like this.

shouldComponentUpdate(nextProps, nextState) {
  //在这个函数被调用时,this.state还没有被改变
}

In the current React design, when shouldComponentUpdate is called, this.state has not been changed. The state change generated by setState is reflected by the parameter nextState, as is componentWillUpdate.

Therefore, in order not to implement a lot of code based on the existing React system, we must not modify this.state before shouldComponentUpdate. The timing of modifying this.state must only be between calling componentWillUpdate and render function.

That is to say, even if setState is known as "synchronously updating" this.state, it cannot actually be updated immediately, because the lifecycle functions shouldComponentUpdate and componentWillUpdate caused by setState have not changed this.state.

It sounds like the solution is not very thorough, it seems to make things more complicated.

The second option: setState automatically triggers the asynchronous component update process

Under this option, when setState returns, this.state has been changed, but the update process is not immediately triggered. React still puts the results generated by setState in the queue, and waits for the update process when the time is right.

This will definitely not work. If setState changes this.state, what should componentUpdate and componentWillUpdate do? These two functions always assume that this.state has not been changed during execution.

This choice will no longer work.

 

The third option: setState does not trigger the component update process at all

The first two choices are not good, then look at this third choice, setState only modifies this.state, and does not start the component update process, then we need another function to actively trigger the update state, but ... if true In this case, why do you need setState?

 

You see, since setState has nothing to do with the update process of components, then we can directly manipulate this.state, right?

If you really like this way, you do n’t even need to redesign React. Now React can play like this: directly operate this.state to synchronously modify the component state, and then call this.setState without any parameters, which is equivalent to empty. A shot, the only purpose is to actively trigger an update status.

In this way, the incrementMultiple function in " setState: How is this API designed? " Can be written like this.

 

  incrementMultiple() {
    this.state.count = this.state.count + 1;
    this.state.count = this.state.count + 1;
    this.state.count = this.state.count + 1;

    this.setState();
  }

I read this.state.count directly three times, and modified this.state.count directly three times. The result is correct. Each call to incrementMultiple really increases the count value on this.state by 3, and the component is drawn again.

how do you feel? Do you think this is a good move, or a bad move?

Anyway, I saw this trick I wrote, and the response was: Ha ha.

If you use this method to write code, then React is not enough React, not Reactive .

Why React is called React

Although React does not hold up the banner of Reactive Programming like Rx.js, it still embodies the idea of ​​Reactive Programming.

Reactive Programming is a programming style like this: change one thing, another thing will respond to change, without using our Code to actively make another thing change.

Everyone has used Excel, and Excel stands for Reactive Programming.

Please imagine that there is such an Excel table, fill 1 in one grid A1, and add the formula = in another grid A2. At [official]this time, A2 is displayed in 2, then, we change A1 to 2, A2 is just It became 4.

That's right, this is Reactive Programming, because after we set the formula, as long as we change one place, another place will automatically change, without the need to press a button or something to call that formula.

Remember that formula about React? [official], Our code is that f , and the nature of the formula in the Excel table. In React, when we change the state of a component through setState, the UI of the component will automatically change. This is the embodiment of Reactive Programming.

If we modify this.state directly, and then call setState, it is like changing the value of A1 in the Excel table, and then pressing a button to change the value of A2 ... how does it look? Not very Reactive.

So, if I want to say how to look at the above method of directly modifying this.state.count, that is: let's all play with React, so don't go back to before liberation.

To sum up, after reading the above three "Redesign React" options, it seems that letting setState update component state synchronously is not a good choice.

Personal suggestion, don't directly operate this.state, you must resist this temptation, otherwise I will regret to reveal this secret trick.

In fact, I am curious, what kind of actual needs hope that setState can modify this.state synchronously? I have not encountered this kind of demand. Perhaps the situation I am dealing with is not complicated enough, but I believe there must be a better solution.

If you really encounter a specific scene and want to setState to change the state synchronously, you can leave a message in the comments, I will help you think about how to deal with it.

Published 35 original articles · won praise 1 · views 6718

Guess you like

Origin blog.csdn.net/qq_36162529/article/details/101210138
Recommended