作为 React 的开发者,我们知道 useLayoutEffect
是在 render
的 task 内执行的,useEffect
是在下一个 task 执行的,可以参考
React 18 源代码学习 14 commitLayoutEffectOnFiber
useLayoutEffect
和 render
阶段是在同一个 Javascript 的调用栈 ( 图中黄色的 Javascript
阶段 )中,此时虽然 DOM 结构已经生成,从 DOM api 获取 DOM 结构也是 React commit
后的的结构,然而浏览器尚且没有得到实际渲染的时机。此 task 结束后,浏览器得到时机进行实际的渲染,渲染后的下一个 Javascript task ( 即执行完 Style
, Layout
, Paint
, Composite
后的下一个 Javascript
阶段 ) 才得以有时机执行 useEffect
的回调。
触发时机
那 useEffect
的调用的触发时机是什么时候呢,参考
React 18 源代码学习 12 commit,通过 debug 发现:在 commit
的阶段开始 flushPassiveEffects
时,就安排了 useEffect
的回调,然后才会执行后续的 commit
阶段。
触发方式
具体安排的方式,可以参考 React 18 源代码学习笔记 4 消息循环 (MessageLoop),更详细的流程如下:
虽然实际出发的位置和出发的回调不同,不过基本流程应该相同。
Screen Shot 2022-09-24 at 20.18.29.png
网友评论