React setState 的执行是异步还是同步
官方文档是这么说的setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.
也就是说,setState 可能同步执行也可能异步执行。直接来结论
同步执行的场景
- 我们自己通过 addEventListen/setTimeout/setInterval/Promise,在这些里面调用
setState
,会同步更新 state 的值,跟在他们后面可以直接拿到更新后的 state。
异步的场景 - React lifecycleMethond/React 封装后的事件响应函数里面,这些是异步,跟在
setState
调用后面不能拿到最新的值。
为什么会这样?
setState
函数内部会有一个 isBatchingUpdate=false
,用来标记是否是异步还是同步,React 生命周期函数跟事件函数,调用前会内部调用batchedUpdates()
,会将这个值设为true
,所以,我们自己的一些函数里面调用了 setState,就绕过了batchedUpdates()
的调用。
当 React 真正开始执行 setState 的时候要注意的。
- 首先,循序执行的多个 setState 是拿不到前一个 setState 更新后的值的。
- 如果向拿到最新的值可以用这个
setState((preState,preProps)=>newState)
。 -
setState(,[callback])
,这个 callback 执行的时机跟componentDidUpdate
一样,建议放到componentDidUpdate
里面做。 -
setState
,一定会触发 render 的流程,但是可以通过shouldComponentUpdate
进行拦截。