When does React-setState update state synchronously

In fact, setState can also update this.state synchronously, I have studied it, really! In some cases, setState can really update this.state synchronously!

The official documentation is not clear about the synchronization behavior of setState, so I can only look at the source code. Hong Kong really, I really do n’t want to look at the source code of React, but there is no better way to encounter this kind of thing. After all, open source software The advantage is that you can see the source code.

Let's talk directly about the conclusion first:

In React, if it is event processing triggered by React (such as event processing triggered by onClick), calling setState will not update this.state synchronously, other setState calls will execute this.state synchronously . The so-called "other than" refers to bypassing the event handler function directly added by React through addEventListener, and the asynchronous call generated by setTimeout / setInterval.

If we use React in a textbook-like way, we will basically not touch the so-called "other than" situation.

Besides, why does this happen:

In the implementation of React's setState function, it will judge whether to update this.state directly or put it in the queue according to a variable isBatchingUpdates , and then say, and isBatchingUpdates defaults to false, which means that setState will update this.state synchronously, but there is a function batchedUpdates , this function will modify isBatchingUpdates to true, and when React will call this batchUpdates before calling the event processing function , the consequence is that the event processing setState controlled by React will not update this.state synchronously.

Is the introduction above a bit boring? I hope it's not too boring. If you don't care about the reason, just remember the conclusion.

In order to show the effect, let's look at a piece of code. On JS Bin , a simple click button increases the count function.

In the onClick function, we call the setState function, and then output this.state on console.log, thereby judging whether setState has updated this.state synchronously.

  onClick() {
    this.setState({count: this.state.count + 1});
    console.log('# this.state', this.state);
  }

In the render function, we use console.log to output a message. Through the render function, we can determine whether the update process has occurred, and then we use three buttons to represent the three event processing methods.

  render() {
    console.log('#enter render');
    return (
      <div>
        <div>{this.state.count}
          <button onClick={this.onClick}>Increment</button>
          <button id="btn-raw">Increment Raw</button>
          <button onClick={this.onClickLater}>Increment Later</button>
        </div>
      </div>
    )

  }

This is the last interface displayed.

The Increment button uses the most formal onClick method to handle click events.

Increment Raw handles click events through addEventListener .

  componentDidMount() {
    document.querySelector('#btn-raw').addEventListener('click', this.onClick);
  }

Increment Later uses setTimeout to handle click events.

  onClickLater() {
    setTimeout(() => {
      this.onClick();
    });
  }

By clicking on three different buttons, we can see different behaviors.

Click Increment, first output this.state without update, and then the render function is executed, it can be seen that the update of this.state is asynchronous, and the update process is only triggered after the setState is executed.

However, if you click Increment Raw or Increment Later, you first execute the render function, and then output the updated this.state. It can be seen that this.state is updated synchronously, and the update process has been completed during the execution of the setState function.

Do you still want setState to update this.state synchronously?

The above experiment clearly shows that if this.state is updated synchronously, each call to setState will trigger a synchronous update process, which will cause the update process to be frequent and will cause performance problems.

So, although React has the function to let setState update this.state synchronously, we still avoid this usage.

Don't use this trick, we can understand a tool, but it does not mean that we should use it.

Published 35 original articles · won praise 1 · views 6718

Guess you like

Origin blog.csdn.net/qq_36162529/article/details/101210322