第一章 JSX(React18源码解析一)
第二章 实现Virtual DOM(React18源码解析二)
第三章 根节点关联根Fiber(React18源码解析三)
第四章 初始化UpdateQueue、添加update(React18源码解析四)
第五章 实现时间切片函数和拷贝Fiber(React18源码解析五)
第六章 构建FiberTree(React18源码解析六)
第七章 commit(React18源码解析七)
第八章 React中的事件(React18源码解析八)
第九章 useReducer、useState(React18源码解析九)
第十章 React的dom diff(React18源码解析十)
第十一章 React的Effect(React18源码解析十一)
第十二章 React的同步、并发渲染(React18源码解析十二)
第十三章 React高优打断低优、饥饿问题(React18源码解析十三)
一.内部调用流程
updateContainer=》
scheduleUpdateOnFiber=》
ensureRootIsScheduled=》
scheduleCallback(Scheduler.unstable_scheduleCallback)=》
performConcurrentWorkOnRoot=》
renderRootSync(root, lanes)=》
prepareFreshStack=》
createWorkInProgress
二.关键实现
//react-18.0.0/packages/scheduler/src/forks/Scheduler.js
//内部使用最小堆和MessageChannel来调用传递过来的callback及performConcurrentWorkOnRoot来实现任务分片
function unstable_scheduleCallback(priorityLevel, callback, options) {
var currentTime = getCurrentTime();
var startTime;
if (typeof options === 'object' && options !== null) {
var delay = options.delay;
if (typeof delay === 'number' && delay > 0) {
startTime = currentTime + delay;
} else {
startTime = currentTime;
}
} else {
startTime = currentTime;
}
var timeout;
switch (priorityLevel) {
case ImmediatePriority:
timeout = IMMEDIATE_PRIORITY_TIMEOUT;
break;
case UserBlockingPriority:
timeout = USER_BLOCKING_PRIORITY_TIMEOUT;
break;
case IdlePriority:
timeout = IDLE_PRIORITY_TIMEOUT;
break;
case LowPriority:
timeout = LOW_PRIORITY_TIMEOUT;
break;
case NormalPriority:
default:
timeout = NORMAL_PRIORITY_TIMEOUT;
break;
}
var expirationTime = startTime + timeout;
var newTask = {
id: taskIdCounter++,
callback,
priorityLevel,
startTime,
expirationTime,
sortIndex: -1,
};
if (enableProfiling) {
newTask.isQueued = false;
}
if (startTime > currentTime) {
newTask.sortIndex = startTime;
//往最小堆中添加任务
push(timerQueue, newTask);
//最小堆出堆
if (peek(taskQueue) === null && newTask === peek(timerQueue)) {
// All tasks are delayed, and this is the task with the earliest delay.
if (isHostTimeoutScheduled) {
// Cancel an existing timeout.
cancelHostTimeout();
} else {
isHostTimeoutScheduled = true;
}
// Schedule a timeout.
requestHostTimeout(handleTimeout, startTime - currentTime);
}
} else {
newTask.sortIndex = expirationTime;
push(taskQueue, newTask);
if (enableProfiling) {
markTaskStart(newTask, currentTime);
newTask.isQueued = true;
}
// 内部使用MessageChannel实现的切片函数,循环调用堆中任务
if (!isHostCallbackScheduled && !isPerformingWork) {
isHostCallbackScheduled = true;
requestHostCallback(flushWork);
}
}
return newTask;
}
//react-18.0.0/packages/react-reconciler/src/ReactFiberWorkLoop.old.js
//根据oldFiber创建newFiber,没有oldFiber直接创建fiber,通过alternate属性相互指向,采用双缓冲技术相互拷贝
function prepareFreshStack(root, lanes) {
root.finishedWork = null;
root.finishedLanes = NoLanes;
workInProgressRoot = root;
const rootWorkInProgress = createWorkInProgress(root.current, null);
workInProgress = rootWorkInProgress;
workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
workInProgressRootExitStatus = RootInProgress;
workInProgressRootFatalError = null;
workInProgressRootSkippedLanes = NoLanes;
workInProgressRootInterleavedUpdatedLanes = NoLanes;
workInProgressRootRenderPhaseUpdatedLanes = NoLanes;
workInProgressRootPingedLanes = NoLanes;
workInProgressRootConcurrentErrors = null;
workInProgressRootRecoverableErrors = null;
return rootWorkInProgress;
}
备注
本文为清晰展现出本文核心逻辑把粘贴的源码中参数校验、typescript类型、不相关逻辑等已删除