其中我们谈到

本节我们深入flushPassiveEffects方法内部探索useEffect的工作原理。

flushPassiveEffects内部会设置优先级,并执行flushPassiveEffectsImpl

flushPassiveEffectsImpl主要做三件事:

  • 调用该useEffect在上一次render时的销毁函数

  • 如果存在同步任务,不需要等待下次事件循环宏任务,提前执行他

本节我们关注前两步。

v16中第一步是同步执行的,在中提到:

基于这个原因,在中,useEffect的两个阶段会在页面渲染后(layout阶段后)异步执行。

接下来我们详细讲解这两个步骤。

这是因为多个组件间可能共用同一个ref

如果不是按照“全部销毁”再“全部执行”的顺序,那么在某个组件useEffect销毁函数中修改的ref.current可能影响另一个组件useEffect回调函数中的同一个refcurrent属性。

在中也有同样的问题,所以他们都遵循“全部销毁”再“全部执行”的顺序。

在阶段一,会遍历并执行所有useEffect销毁函数

其中pendingPassiveHookEffectsUnmount数组的索引i保存需要销毁的effecti+1保存该effect对应的fiber

pendingPassiveHookEffectsUnmount数组内push数据的操作发生在layout阶段 commitLayoutEffectOnFiber方法内部的schedulePassiveEffects方法中。

其中向pendingPassiveHookEffectsMount中数据的操作同样发生在schedulePassiveEffects中。