从一道面试题说起
这个我在之前研究过,不过并不知道这道题,只是在实际工作中被这种东西困惑过~
情况一: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,一定是异步的
总结
setState 的表现会因调用场景的不同而不同
- 在 React 钩子函数及合成事件中,它表现为异步
- 在 setTimeout、setInterval 等函数中,包括在 DOM 原生事件中,它都表现为同步
这个差异是由事务机制和批量更新机制工作方式决定的。
相信你已经对 setState 有了知根知底的理解
React 16 以来,整个 React 核心算法被重写
setState 也不可避免地被“Fiber”化