React users know that setState is an important way to manage state. Here’s a quick introduction to the API.
SetState does not immediately change the value of state in the component
As we know, this.state is read-only, and the updated state cannot be changed directly, but through the this.setState method. Why is that? This. state is just an object, and it makes no sense for us to change its value. If you think about it, the reason we change state is to change the rendering state of the page. So React’s setState method is designed to rerender the page.
We can print the value of this.state after setState and see that it hasn’t changed. It’s the same value as before. If we need to setState multiple times in a short period of time, and each time the value of the setState is related to the previous state, we need to use a function as an argument to setState. This function takes two arguments (the current state and the current props). Here’s an example:
// The result may be that this.state.value is only increased by 1
function test1() {
this.setState({ value: this.state.value + 1 });
this.setState({ value: this.state.value + 1 });
this.setState({ value: this.state.value + 1 });
}
// In other words, the result is exactly what we want
function test2() {
this.setState((state, props) = > ({ value: state.value + 1 }));
this.setState((state, props) = > ({ value: state.value + 1 }));
this.setState((state, props) = > ({ value: state.value + 1 }));
}
Copy the code
Because of the use of functional setState, React ensures that each time the function is called, the state has merged the previous state changes.
SetState also has a second argument, callback, so the following is fine:
this.setState({ value: this.state.value + 1 }, (val) => {
this.setState({ value: this.state.value + 1= > {}, ()this.setState({ value: this.state.vavlue + 1 });
});
});
Copy the code
Personally, I prefer to write a functional setState.
It seems that sometimes setState updates state synchronously, such as using setTimeout/setInterval or addEventListener to handle events. Refer to setState when the status is updated synchronously
Multiple setstates merge
Previously we learned that setState does not change the value of state immediately, but instead puts it in a task queue, eventually merging multiple setStates to update the page at once. So we can call setState multiple times in our code, each time focusing on the current field.
In addition, it is important to note that setState triggers page rerendering through the following lifecycle:
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
The value of state is changed only when it is in the render field. It is changed when it is in the shouldComponentUpdate and componentWillUpdate fields. The test results are as follows:
// shouldComponentUpdate: 0
// componentWillUpdate: 0
// render: 1
// componentDidUpdate: 1
// shouldComponentUpdate: 1
// componentWillUpdate: 1
// render: 2
// componentDidUpdate: 2
// shouldComponentUpdate: 2
// componentWillUpdate: 2
// render: 3
// componentDidUpdate: 3
Copy the code
Reference: setState: How well is this API designed