React setState 相关
react 前端 javascript
React setState
setState 三种用法:
- setState({name: ‘niko’})
- setState((state, props) => {return {name: ‘niko’}})
- 传入回调函数:setState({name: ‘niko’}, () => {console.log(this.state.name)})
因为 React18 之后,setState完全都是异步的,setState({name: 'niko'}) 这样执行完之后,立刻访问 this.state.name 还是会取到原来的值。
this.state = {count: 0}
increment() {
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
console.log(this.state.count); // 1️
}
在 React18 之前,以下情况setState是同步的:
- Promise.then 回调/setTimeout/原生 DOM 事件的回调等。
在 React18 中,可以通过 flushSync 实现同步。
this.state = {count: 0}
increment() {
// this.setState({ count: this.state.count + 1 });
// this.setState({ count: this.state.count + 1 });
// this.setState({ count: this.state.count + 1 });
flushSync(() => {
this.setState({ count: this.state.count + 1 });
});
flushSync(() => {
this.setState({ count: this.state.count + 1 });
});
flushSync(() => {
this.setState({ count: this.state.count + 1 });
});
console.log(this.state.count); // 3
}
如果连续执行多个 setState, 比如
this.state = {
count: 0;
}
handle() {
this.setState({count: this.state.count + 1})
this.setState({count: this.state.count + 1})
this.setState({count: this.state.count + 1})
}
此时 state 的值是 1,因为 setState 执行后,state 的值不会立刻被修改,而且 React 会对多次 setState 做合并,Object.assign(),合并时对象中的 count 都是 1。要解决这个问题,可以使用传入函数的方式处理
this.state = {
count: 0;
}
handle() {
this.setState((state) => {count: state.count + 1})
this.setState((state) => {count: state.count + 1})
this.setState((state) => {count: state.count + 1})
}
此时 state 的值是 3,因为会依次执行队列中的函数,然后合并结果。