React高级进阶教程-setState到底是同步的还是异步的?

155 阅读1分钟

image.png

从一道面试题说起

这个我在之前研究过,不过并不知道这道题,只是在实际工作中被这种东西困惑过~

情况一:setCount 直接读 count 值并未发生变化 情况二:连续 setCount 三次,值只增加了 1 情况三:定时器0s后输出,一个2、一个1

const reduce = setTimeout(() => {
console.log(this.state.count)
this.setState({
    count: this.state.count + 1
})
console.log(this.state.count)
}, 0)
  • “神奇时刻”到底何时发生?
  • 所谓的“恰恰好”又如何界定呢?
  • state 到底是在哪个环节发生了变化呢?

reduce 方法里面的 setState 竟然是同步更新的

“同步现象”背后的故事:从源码角度看 setState 工作流

为什么 setTimeout 可以将异步变为同步呢?

并不是 setTimeout 改变了 setState

而是 setTimeout 帮助 setState “逃脱” 了 React 对它的管控

只要是在 React 管控下的 setState,一定是异步的

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

总结

setState 的表现会因调用场景的不同而不同

  • 在 React 钩子函数及合成事件中,它表现为异步
  • 在 setTimeout、setInterval 等函数中,包括在 DOM 原生事件中,它都表现为同步

这个差异是由事务机制和批量更新机制工作方式决定的。

相信你已经对 setState 有了知根知底的理解

React 16 以来,整个 React 核心算法被重写

setState 也不可避免地被“Fiber”化