react-reconciler包的运作流程
- 输入: 暴露api函数(如: scheduleUpdateOnFiber), 供给其他包(如react包)调用
- 注册调度任务: 与调度中心(scheduler包)交互, 注册调度任务task, 等待任务回调.
- 执行任务回调: 在内存中构造出fiber树, 同时与与渲染器(react-dom)交互, 在内存中创建出与fiber对应的DOM节点.
- 输出: 与渲染器(react-dom)交互, 渲染DOM节点.
scheduleUpdateOnFiber
export function scheduleUpdateOnFiber(
fiber: Fiber,
lane: Lane,
eventTime: number,
) {
const root = markUpdateLaneFromFiberToRoot(fiber, lane);
if (lane === SyncLane) {
if (
(executionContext & LegacyUnbatchedContext) !== NoContext &&
(executionContext & (RenderContext | CommitContext)) === NoContext
) {
performSyncWorkOnRoot(root);
} else {
ensureRootIsScheduled(root, eventTime);
}
} else {
ensureRootIsScheduled(root, eventTime);
}
}
ensureRootIsScheduled
function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
const existingCallbackNode = root.callbackNode;
const nextLanes = getNextLanes(
root,
root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
);
const newCallbackPriority = returnNextLanesPriority();
if (nextLanes === NoLanes) {
return;
}
if (existingCallbackNode !== null) {
const existingCallbackPriority = root.callbackPriority;
if (existingCallbackPriority === newCallbackPriority) {
return;
}
cancelCallback(existingCallbackNode);
}
let newCallbackNode;
if (newCallbackPriority === SyncLanePriority) {
newCallbackNode = scheduleSyncCallback(
performSyncWorkOnRoot.bind(null, root),
);
} else if (newCallbackPriority === SyncBatchedLanePriority) {
newCallbackNode = scheduleCallback(
ImmediateSchedulerPriority,
performSyncWorkOnRoot.bind(null, root),
);
} else {
const schedulerPriorityLevel = lanePriorityToSchedulerPriority(
newCallbackPriority,
);
newCallbackNode = scheduleCallback(
schedulerPriorityLevel,
performConcurrentWorkOnRoot.bind(null, root),
);
}
root.callbackPriority = newCallbackPriority;
root.callbackNode = newCallbackNode;
}
performSyncWorkOnRoot
function performSyncWorkOnRoot(root) {
let lanes;
let exitStatus;
lanes = getNextLanes(root, NoLanes);
exitStatus = renderRootSync(root, lanes);
if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
}
const finishedWork: Fiber = (root.current.alternate: any);
root.finishedWork = finishedWork;
root.finishedLanes = lanes;
commitRoot(root);
ensureRootIsScheduled(root, now());
return null;
}
performConcurrentWorkOnRoot
- 如果本次渲染被中断, 最后返回一个新的 performConcurrentWorkOnRoot 函数, 等待下一次调用
function performConcurrentWorkOnRoot(root) {
const originalCallbackNode = root.callbackNode;
const didFlushPassiveEffects = flushPassiveEffects();
if (didFlushPassiveEffects) {
if (root.callbackNode !== originalCallbackNode) {
return null;
} else {
}
}
let lanes = getNextLanes(
root,
root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
);
let exitStatus = renderRootConcurrent(root, lanes);
if (
includesSomeLane(
workInProgressRootIncludedLanes,
workInProgressRootUpdatedLanes,
)
) {
prepareFreshStack(root, NoLanes);
} else if (exitStatus !== RootIncomplete) {
if (exitStatus === RootErrored) {
}.
const finishedWork: Fiber = (root.current.alternate: any);
root.finishedWork = finishedWork;
root.finishedLanes = lanes;
finishConcurrentRender(root, exitStatus, lanes);
}
ensureRootIsScheduled(root, now());
if (root.callbackNode === originalCallbackNode) {
return performConcurrentWorkOnRoot.bind(null, root);
}
return null;
}
CommitRoot:
function commitRootImpl(root, renderPriorityLevel) {
const finishedWork = root.finishedWork;
const lanes = root.finishedLanes;
root.finishedWork = null;
root.finishedLanes = NoLanes;
root.callbackNode = null;
let firstEffect = finishedWork.firstEffect;
if (firstEffect !== null) {
const prevExecutionContext = executionContext;
executionContext |= CommitContext;
nextEffect = firstEffect;
do {
commitBeforeMutationEffects();
} while (nextEffect !== null);
nextEffect = firstEffect;
do {
commitMutationEffects(root, renderPriorityLevel);
} while (nextEffect !== null);
root.current = finishedWork;
nextEffect = firstEffect;
do {
commitLayoutEffects(root, lanes);
} while (nextEffect !== null);
nextEffect = null;
executionContext = prevExecutionContext;
}
ensureRootIsScheduled(root, now());
return null;
}
- commitBeforeMutationEffects
- dom 变更之前, 主要处理副作用队列中带有Snapshot,Passive标记的fiber节点
- commitMutationEffects
- dom 变更, 界面得到更新. 主要处理副作用队列中带有Placement, Update, Deletion, Hydrating标记的fiber节点.
- commitLayoutEffects
- dom 变更后, 主要处理副作用队列中带有Update | Callback标记的fiber节点
|