流程概览
- commitRoot方法是commit阶段工作的起点。fiberRootNode会作为传参,commitRoot(root);
- 在rootFiber.firstEffect上保存了一条需要执行副作用的Fiber节点的单向链表effectList,这些Fiber节点的updateQueue中保存了变化的props;这些副作用对应的DOM操作在commit阶段执行
- 除此之外,一些生命周期钩子(比如componentDidXXX)、hook(比如useEffect)需要在commit阶段执行。
- commit阶段的主要工作(即Renderer的工作流程)分为三部分:
- before mutation阶段(执行DOM操作前);
- mutation阶段(执行DOM操作);
- layout阶段(执行DOM操作后);
- 在before mutation阶段之前和layout阶段之后还有一些额外工作,涉及到比如useEffect的触发、优先级相关的重置、ref的绑定/解绑。
beforeMutation前
do {
// 触发useEffect回调与其他同步任务。由于这些任务可能触发新的渲染,所以这里要一直遍历执行直到没有任务
flushPassiveEffects()
} while (rootWithPendingPassiveEffects !== null)
// root指 fiberRootNode
// root.finishedWork指当前应用的rootFiber
const finishedWork = root.finishedWork
// 凡是变量名带lane的都是优先级相关
const lanes = root.finishedLanes
if (finishedWork === null) {
return null
}
root.finishedWork = null
root.finishedLanes = NoLanes
// 重置Scheduler绑定的回调函数
root.callbackNode = null
root.callbackId = NoLanes
let remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes)
// 重置优先级相关变量
markRootFinished(root, remainingLanes)
// 清除已完成的discrete updates,例如:用户鼠标点击触发的更新。
if (rootsWithPendingDiscreteUpdates !== null) {
if (
!hasDiscreteLanes(remainingLanes) &&
rootsWithPendingDiscreteUpdates.has(root)
) {
rootsWithPendingDiscreteUpdates.delete(root)
}
}
// 重置全局变量
if (root === workInProgressRoot) {
workInProgressRoot = null
workInProgress = null
workInProgressRootRenderLanes = NoLanes
} else {
}
// 将effectList赋值给firstEffect
// 由于每个fiber的effectList只包含他的子孙节点
// 所以根节点如果有effectTag则不会被包含进来
// 所以这里将有effectTag的根节点插入到effectList尾部
// 这样才能保证有effect的fiber都在effectList中
let firstEffect
if (finishedWork.effectTag > PerformedWork) {
if (finishedWork.lastEffect !== null) {
finishedWork.lastEffect.nextEffect = finishedWork
firstEffect = finishedWork.firstEffect
} else {
firstEffect = finishedWork
}
} else {
// 根节点没有effectTag
firstEffect = finishedWork.firstEffect
}
layout后
const rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
if (rootDoesHavePassiveEffects) {
rootDoesHavePassiveEffects = false;
rootWithPendingPassiveEffects = root;
pendingPassiveEffectsLanes = lanes;
pendingPassiveEffectsRenderPriority = renderPriorityLevel;
} else {}
if (remainingLanes !== NoLanes) {
if (enableSchedulerTracing) {
}
} else {
}
if (enableSchedulerTracing) {
if (!rootDidHavePassiveEffects) {
}
}
if (remainingLanes === SyncLane) {
}
ensureRootIsScheduled(root, now());
flushSyncCallbackQueue();
return null;
beforeMutation阶段

mutation阶段

layout阶段
