Appearance
flushPassiveEffects
Commit 阶段的第一步,其主要作用是:
- 对需要被删除的旧节点的 和 存在 Passive 副作用的节点执行 destroy 函数
- 对存在 Passive 副作用的节点 执行 create 函数, 并将返回值添加到 update.destroy 中
- 对 需要被删除的旧节点按照深度遍历优先的顺序 进行新旧节点的解耦操作
commitPassiveUnmountEffects
- 对于移除的旧节点树
- 通过遍历
fiber.deletions去 按照父 => 子 的顺序执行useEffect(HookPassive)类型的销毁操作 - 按照按照深度优先的规则 对新旧节点进行解耦操作
js
if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
// 获取被删除的旧节点数组
const deletions = fiber.deletions;
if (deletions !== null) {
for (let i = 0; i < deletions.length; i++) {
const fiberToDelete = deletions[i];
// 将下一个待处理的副作用指向 被移除的旧节点
nextEffect = fiberToDelete;
commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
fiberToDelete,
fiber
);
}
nextEffect = fiber;
}
}其核心是处理 保存在 fiber.deletions 中的需要被移除的旧节点,对于这些旧节点树,其处理流程如下:
js
/**
* Commit阶段: 执行标记删除的旧节点的
* 1. 按照 父 => 子 的顺序 执行 effect中HookPassive类型的 destroy 操作
* 2. 按照深度优先的规则 对新旧节点进行解耦操作
* @param {*} deletedSubtreeRoot
* @param {*} nearestMountedAncestor
*/
function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
deletedSubtreeRoot: Fiber,
nearestMountedAncestor: Fiber | null
) {
while (nextEffect !== null) {
const fiber = nextEffect;
// 删除操作的顺序是 父节点 -> 子节点
setCurrentDebugFiberInDEV(fiber);
// 执行 HookPassive 类型的副作用的卸载操作
commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
resetCurrentDebugFiberInDEV();
// 如果存在子节点 就优先进入子节点
const child = fiber.child;
if (child !== null) {
child.return = fiber;
nextEffect = child;
} else {
commitPassiveUnmountEffectsInsideOfDeletedTree_complete(
deletedSubtreeRoot
);
}
}
}- 对于当前 FiberNode 数中的节点
按照深度优先 子 => 兄弟 => 父 的顺序 执行 useEffect(HookPassive) 类型的销毁操作
js
// 2. 对于当前FiberNode数中的节点
// 按照深度优先 子 => 兄弟 => 父 的顺序 执行HookPassive类型的销毁操作
if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
child.return = fiber;
nextEffect = child;
} else {
commitPassiveUnmountEffects_complete();
}其是按照深度优先的顺序,找到存在 PassiveMask 副作用的叶子节点,然后对于叶子节点执行 HookPassive 类型的 destroy 操作
commitPassiveMountEffects
按照深度优先的顺序, 执行存在 PassiveMask 副作用的节点 的 create 函数,并将返回值添加到 update.destroy 中
js
/**
* 按照深度优先的规则执行存在 Passive类型副作用的函数的 effect.create 方法 并将返回值赋值给 effect.destroy
* @param {*} flags
* @param {*} finishedWork
*/
function commitHookEffectListMount(flags: HookFlags, finishedWork: Fiber) {
const updateQueue: FunctionComponentUpdateQueue | null =
(finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
const firstEffect = lastEffect.next;
let effect = firstEffect;
do {
if ((effect.tag & flags) === flags) {
// Mount
// 执行 effect 的 create 方法
const create = effect.create;
// 并将create方法的返回值赋值给effect的destroy属性
effect.destroy = create();
}
effect = effect.next;
} while (effect !== firstEffect);
}
}