Update the state setState
The React type component update page can access the this.setState(stateChange, callback) method through the component instance.
setState
Function that takes two arguments: to update the state and to re-invoke the render of the current component- The first argument: isobjectorfunctionIn the framework, the object itself or the return value of a function call is similar to the current state
Object.assign()
的merge./ / object this.setState({ counter: this.state.counter + this.props.increment, }) / / function this.setState((preState, props) = > ({ counter: preState.counter + props.increment })) Copy the code
- The second parameter: isThe callback functionThe second parameter callback is executed after the state data merge operation is complete and before the component’s render function is called.
render() { let { count } = this.state return <div> <button onClick={()= >{this.setState({count: count + 1}, () => {console.log(' change before count', count); Console. log(' count after change ', this.state.count); })}}> point I increment 1</button>The current counter is {count}</div> } Copy the code
- The first argument: isobjectorfunctionIn the framework, the object itself or the return value of a function call is similar to the current state
setState()
The calling code itself isSynchronous executionBut both the merge operation and the call to render function areAsynchronous execution(microtasks). So be careful, in the code that executes synchronously, the following code, after two values, the merge and re-render components are performed, so both values are the same.state = { count: 0 } // ❌ The value of this.state.count is the same as the value of 0 + 1 in the first call handle = () = > { this.setState({ count: this.state.count + 1 }, () = >{... })this.setState({ count: this.state.count + 1 }, () = >{... })}// ✅ write the first parameter of setState as a function to receive the value of each update handle = () = > { this.setState(preState= > ({ count: preState.count + 1 }), () = >{... })this.setState(preState= > ({ count: preState.count + 1 }), () = >{... })}Copy the code
SetState Execution flow
Did not read the source code or analysis of the source code article verification, pure self-testing, in line with the test results
- When the first argument to the setState function isobjectWhen:
- Execute synchronization code: setState function call, the first parameter object member value, register the following three asynchronous microtasks, continue to execute the following synchronization code
- Clear (execute) the microtasks in the current macro task:
- Perform the merge operation task to merge the first parameter object with the current state object (the state data is updated)
- The second parameter callback of setState is executed
- Execute the render function of the current component (view updated)
- When the first argument to the setState function isfunctionWhen:
- Execute synchronization code: the setState function call, with the first parameter function definition, registers the following four asynchronous microtasks to continue with the subsequent synchronization code
- Clear (execute) the microtasks in the current macro task:
- Execute the first argument function, get the return value object, and evaluate the member of the object
- Perform the merge operation task to merge the return value object with the current state object (the state data is updated)
- The second parameter callback of setState is executed
- Execute the render function of the current component (view updated)
SetXXX in useState Hook is the same as the setState function of the class component, except that: 1. SetXXX is not overloaded, only one parameter, no second parameter callback. 2. SetXXX update status is a replacement operation, not a merge operation
Multiple calls to merge render
React optimizes performance when the setState function is called multiple times.
-
Call setState in synchronous code environment: In the normal React event flow, a class component executes setState multiple times or a function component executes setXXX multiple times in a useState and only calls the render again once. This is called merge render
If the render is not merged, the component will have to be rerendered every time the setState update function is executed, resulting in an invalid render and a waste of time (because the last render overwrites all previous render effects).
So React will group some set states that can be updated together, merge them, and render only one last time.
-
Call setState in asynchronous code environment: Execute setState and setXXX in useState multiple times in asynchronous events such as setTimeout, promise. then, and call render on each execution
SetTimeout is out of react’s control, and React cannot add transaction logic to the setTimeout callback code (unless React overrides setTimeout).
When faced with setTimeout/setInterval/Promise. Then (fn)/fetch callback/XHR callback network, the react is unable to control.