setState 同步还是异步?
setState本事代码的执行肯定是同步的,这里的异步是指的多个state会合并到一起进行批量更新。同步还是异步取决于它被调用的环境。
异步的情况:
由React控制的事件处理函数,以及生命周期函数调用setState时表现为异步 。
大部分开发中用到的都是React封装的事件,比如onChange、onClick、onTouchMove等(合成事件中),这些事件处理函数中的setState都是异步处理的。
同步的情况:
React控制之外的事件中调用setState是同步更新的。
比如原生js绑定的事件,setTimeout/setInterval,ajax,promise.then内等 React 无法掌控的
APIs情况下,setState是同步更新state的。
原因?
在 React 的 setState
函数实现中,会根据一个变量 isBatchingUpdate
判断是直接更新 this.state
还是放到队列中回头再说,而且 isBatchingUpdate
默认是 false
,也就是表示 setState
会同步更新 this.state
,但是,有一个函数 batchedUpdate
,这个函数会把 isBatchingUpdate
修改为 true
,而当 React
在调用事件处理函数之前就会调用这个 batchedUpdates
,造成的后果,就是由 React
控制的事件处理过程 setState
不会同步更新 this.state
注意:
setState
的 异步
并不是说内部由异步代码实现,其实本身执行的过程和代码是同步的,只是合成事件和钩子函数的调用在更新之前,导致在合成事件和钩子函数中没法里吗拿到更新后的值,形成了所谓的"异步"
但是可以通过 setState(partialState, callback)
中的 callback
拿到更新后的结果