官方实现
2023年06月11日
一、/react/packages/react-reconciler/src/ReactFiberWorkLoop.new.js
function performUnitOfWork(unitOfWork: Fiber): void {
// The current, flushed, state of this fiber is the alternate. Ideally
// nothing should rely on this, but relying on it here means that we don't
// need an additional field on the work in progress.
const current = unitOfWork.alternate;
setCurrentDebugFiberInDEV(unitOfWork);
let next;
if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
startProfilerTimer(unitOfWork);
next = beginWork(current, unitOfWork, subtreeRenderLanes);
stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
} else {
next = beginWork(current, unitOfWork, subtreeRenderLanes);
}
resetCurrentDebugFiberInDEV();
unitOfWork.memoizedProps = unitOfWork.pendingProps;
if (next === null) {
// If this doesn't spawn new work, complete the current work.
completeUnitOfWork(unitOfWork);
} else {
workInProgress = next;
}
ReactCurrentOwner.current = null;
}
由上可知,render
可以分为两个阶段
-
beginWork
: 是向下调和的过程。就是由fiberRoot
按照child
指针逐层向下调和,期间会执行函数组件,实例类组件,diff
调和子节点,打不同effectTag
。 -
completeUnitOfWork
: 是向上归并的过程,如果有兄弟节点,会返回sibling
兄弟,没有返回return
父级,一直返回到fiebrRoot
,期间可以形成effectList
,对于初始化流程会创建DOM
,对于DOM
元素进行事件收集,处理style
,className
等。
这么一上一下,构成了整个 fiber
树的调和