# state细节详解及React18的自动批处理
# 自动批处理
自动批处理,即有助于减少在状态更改时发生的重新渲染次数。在React18之前也有批处理的,但是在Promise、setTimeout、原生事件中是不起作用的。
实际上自动批处理指的是,同一时机多次调用setState()
方法的一种处理机制。
handleClick = () => {
this.setState({
msg: 'hi'
});
this.setState({
count: 1
});
}
这里的代码当点击触发后,虽然调用了两次setState()
方法,但是只会触发一次render()
方法的重新执行。那么这就是所谓的自动批处理机制,这样是有助于性能的,减少重新执行的次数。
而且不管在什么时机下,都不会有问题的,这个在React18版本之前并不是所有的情况都好用的,比如:定时器。
handleClick = () => {
setTimeout(()=>{
this.setState({
msg: 'hi'
});
this.setState({
count: 1
});
}, 2000)
}
上面代码在React18之前的版本中,将会触发两次render()
方法。默认是自动批处理的,当然也可以改成不是自动批处理的方式,通过ReactDOM.flushSync
这个方法。
handleClick = () => {
ReactDOM.flushSync(()=>{
this.setState({
msg: 'hi'
});
})
ReactDOM.flushSync(()=>{
this.setState({
count: 1
});
})
}
# 异步处理
既然React18对多次调用采用的是自动批处理机制,那么就说明这个setState()
方法是异步的,所以要注意方法调用完后,我们的state数据并不会立即发生变化,因为state可能会被先执行了。
handleClick = () => {
/* this.setState({
count: this.state.count + 1
});
console.log( this.state.count ); */
this.setState({
count: this.state.count + 1
}, ()=>{ //异步执行结束后的回调函数
console.log( this.state.count );
});
}
可利用setState()
方法的第二个参数来保证数据更新后再去执行。这里还要注意同样的数据修改只会修改一次,可利用setState()
的回调函数写法来保证每一次都能触发。
handleClick = () => {
/* this.setState({
count: this.state.count + 1
});
this.setState({
count: this.state.count + 1
});
this.setState({
count: this.state.count + 1
}); */
this.setState((state)=> ({count: state.count + 1}));
this.setState((state)=> ({count: state.count + 1}));
this.setState((state)=> ({count: state.count + 1}));
}
这样页面按钮点击一次,count会从0直接变成了3。