官方对其描述是:State Updates May Be Asynchronous.
也就是说,setState
表现出来可能是同步的也可能是异步的,要根据情况的不同来进行判断。
实战例子
下面是一个 setState
的例子,猜猜答案是什么?
class App extends React.Component { state = { val: 0 } componentDidMount() { this.setState({ val: this.state.val + 1 }) console.log(this.state.val) this.setState({ val: this.state.val + 1 }) console.log(this.state.val) setTimeout(_ => { this.setState({ val: this.state.val + 1 }) console.log(this.state.val); this.setState({ val: this.state.val + 1 }) console.log(this.state.val) }, 0) } handleClick = () => { this.setState({ val: this.state.val + 1 }) console.log(this.state.val) this.setState({ val: this.state.val + 1 }) console.log(this.state.val) }; render() { return <div onClick={handleClick}{this.state.val}</div> }}
答案是 0 0 2 3
,当我们点击 div
标签时,输出为 3 3
。
在 React 中,当在生命周期或者是 React 的合成事件里调用 setState
就会表现出异步,而如果你是在原生事件中或者是通过 setTimeout/setInterval
产生的异步调用里进行 setState
则会表现出同步。
为什么?
我们通过上面的例子知道了在什么情况下,它会表现出不同的结果,但是为什么会这样呢?
这里先明确一点,setState
表现出的异步不是指在 React 内部是通过异步实现的,其原本的执行过程都是同步的,只是在 React 中,为了优化所作的批处理机制给开发者造成了一种异步的假象。
那为啥原生事件和 setTimeout/setInterval
里会表现出同步呢?是因为这两者都脱离了 React 的执行环境,所以 React 的批处理机制并没有对其进行处理,所以表现出来就是同步的。而当我们使用如 onClick
的时候,我们使用的是 React 提供的合成事件,也就是说这是受 React 管制的,所以表现出异步,当然了,想要知道更深层次的原因就需要去阅读一下相关的源码了,这里就不展开了,有兴趣的朋友可以读一读。
非常感谢您的阅读,欢迎关注、转发、分享支持我。