Understanding of the synchronous or asynchronous problem of setState in React

Understanding of the synchronous or asynchronous problem of setState in React

1. Is setState synchronous? asynchronous?

In React's class components, we can use the setState method to update the state. But sometimes after using setState, the latest data cannot be obtained.

In fact, the execution process of setState itself in React is synchronized with the code, which is only caused by the performance optimization mechanism of the React framework itself. In React, synthetic events and lifecycle functions are called before updates, which results in the failure to immediately obtain updated values ​​in synthetic events and lifecycle functions, thus forming an asynchronous form.

If the setState method is called n times in a synthetic event, if React is not optimized, the current component will be rendered n times, which is a great waste of performance. Therefore, for performance reasons, React merges multiple calls to the setState method into one execution. When setState is executed, the data in the state is not updated immediately.

As mentioned earlier, calling setState directly in React's synthetic events and lifecycle functions will behave asynchronously.

In addition, if you bypass React's performance optimization mechanism and use setState in native events or setTimeout, it will behave synchronously.

2. Behaves as asynchronously

1. React Synthetic Events

Events used directly in React, such as onChange, onClick, etc., are events encapsulated by React. They are synthetic events and are managed by React. Then due to the performance optimization mechanism, calling setState directly in the synthetic event will appear asynchronous.

In the following code, in the synthetic event onClick, the count in the state is directly increased by 1, and the value of count is printed afterwards. As a result, when the button is clicked for the first time, 0 will be printed instead of the latest 1.

state = { count: 0 };
add = () => {
    this.setState({ count: this.state.count + 1 });
    console.log(this.state.count); // 0
};
render() {
    return (
        <>
            <div>Current count: {this.state.count}</div>
            <button onClick={this.add}>add</button>
        </>
    );
}

2. Lifecycle functions

The lifecycle function is also managed by React. Calling setState directly in the lifecycle function will also behave asynchronously.

In the following code, in the lifecycle componentDidMount function, the count in the state is increased by 1, and the value of count is printed afterwards. The result is 0 instead of the latest 1.

state = { count: 0 };
componentDidMount() {
    this.setState({ count: this.state.count + 1 });
    console.log(this.state.count); // 0
}
render() {
    return (
        <>
            <div>Current count: {this.state.count}</div>
            <button>add</button>
        </>
    );
}

3. Appears as synchronization

1. Native events

The execution process of setState itself is synchronous. Using native events and bypassing React's management will show a synchronous form.

The following code obtains the DOM element by id and binds the click event using native methods. In the click event, add 1 to the count in the state, and then print the value of count. As a result, the latest count value 1 will be printed.

state = { count: 0 };
componentDidMount() {
    const btn = document.getElementById('btn');
    btn.onclick = () => {
        this.setState({ count: this.state.count + 1 });
        console.log(this.state.count); // 1
    };
}
render() {
    return (
        <>
            <div>Current count: {this.state.count}</div>
            <button id="btn">add</button>
        </>
    );
}

2. setTimeout

The following code writes a timer setTimeout in the life cycle componentDidMount function. Inside setTimeout, the count in the state is increased by 1, and the value of count is printed afterwards. As a result, the latest count value 1 will be printed.

Although setState is also written in the componentDidMount function of the life cycle, it is not written directly in componentDidMount, but is wrapped with a layer of setTimeout. In this way, setState behaves synchronously.

state = { count: 0 };
componentDidMount() {
    setTimeout(() => {
        this.setState({ count: this.state.count + 1 });
        console.log(this.state.count); // 1
    }, 0);
}
render() {
    return (
        <>
            <div>Current count: {this.state.count}</div>
            <button>add</button>
        </>
    );
}

4. The second parameter of setState

Regardless of whether setState is written in object-oriented or functional-oriented form, there is a second parameter, which is an optional callback function. This callback function is called only after the state is updated and the interface is updated (after render is called).

As shown in the following code, although setState is called directly in componentDidMount, the value of count is printed in the callback function of setState, and the latest value 1 is obtained. Because the callback function is called after the state is updated, of course the latest count can be obtained.

state = { count: 0 };
componentDidMount() {
    this.setState({ count: this.state.count + 1 }, () => {
        console.log(this.state.count); // 1
    });
}
render() {
    return (
        <>
            <div>Current count: {this.state.count}</div>
            <button>add</button>
        </>
    );
}

This is the end of this article about understanding the synchronous or asynchronous problem of setState in React. For more relevant content about setState synchronous or asynchronous in React, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Code analysis of synchronous and asynchronous setState issues in React
  • The use of setState in React and the use of synchronous and asynchronous
  • Use of setState synchronous and asynchronous scenarios in React

<<:  Detailed explanation of MySQL three-value logic and NULL

>>:  About the "occupational disease" of designers

Recommend

How to verify whether MySQL is installed successfully

After MySQL is installed, you can verify whether ...

Detailed steps to install docker in 5 minutes

Installing Docker on CentOS requires the operatin...

A brief discussion on the optimization of MySQL paging for billions of data

Table of contents background analyze Data simulat...

Mysql sql slow query monitoring script code example

1. Modify my.cnf #The overall effect is that both...

jQuery realizes the full function of shopping cart

This article shares the specific code of jQuery t...

Docker Data Storage Volumes Detailed Explanation

By default, the reading and writing of container ...

About IE8 compatibility: Explanation of the X-UA-Compatible attribute

Problem description: Copy code The code is as fol...

How to connect to MySQL remotely through Navicat

Using Navicat directly to connect via IP will rep...

Details of watch monitoring properties in Vue

Table of contents 1.watch monitors changes in gen...

HTML multimedia application: inserting flash animation and music into web pages

1. Application of multimedia in HTML_falsh animat...

JavaScript to achieve product query function

This article example shares the specific code of ...

Linux implements the source code of the number guessing game

A simple Linux guessing game source code Game rul...

Detailed steps to install MySQL 5.7 via YUM on CentOS7

1. Go to the location where you want to store the...