第一章 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源码解析十三)
commit任务和调用栈
任务:
react在commit阶段根据fiber.flags即副作业标识从下往上的递归出来真实dom,或更新或插入父dom等
调用栈:
commitRoot=>
commitRootImpl=>
//packages/react-reconciler/src/ReactFiberWorkLoop.old.js
commitMutationEffects=>
commitMutationEffectsOnFiber=>
recursivelyTraverseMutationEffects=>commitMutationEffectsOnFiber
commitReconciliationEffects=>commitPlacement
//packages/react-reconciler/src/ReactFiberCommitWork.js
commitMutationEffectsOnFiber函数(有删减,只列举原生节点这一种情况)
function commitMutationEffectsOnFiber(finishedWork,root,lanes){
const current = finishedWork.alternate;
const flags = finishedWork.flags;
switch (finishedWork.tag) {
case HostComponent: {
//根据fiber类型走不同分支,
//recursivelyTraverseMutationEffects会向下递归调用commitMutationEffectsOnFiber,
//当下面的节点处理完毕后再调用commitReconciliationEffects处理本节点,
//本质是一个从root开始递归向下,再递归向上处理的过程
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
commitReconciliationEffects(finishedWork);
//处理ref
if (flags & Ref) {
if (current !== null) {
safelyDetachRef(current, current.return);
}
}
if (supportsMutation) {
//重置文本节点
if (finishedWork.flags & ContentReset) {
const instance = finishedWork.stateNode;
try {
resetTextContent(instance);
} catch (error) {
captureCommitPhaseError(finishedWork, finishedWork.return, error);
}
}
//根据fiber.updateQueue更新原生节点
if (flags & Update) {
const instance = finishedWork.stateNode;
if (instance != null) {
const newProps = finishedWork.memoizedProps;
const oldProps =
current !== null ? current.memoizedProps : newProps;
const type = finishedWork.type;
try {
commitUpdate(instance, type, oldProps, newProps, finishedWork);
} catch (error) {
captureCommitPhaseError(finishedWork, finishedWork.return, error);
}
}
}
}
return;
}
}
}
recursivelyTraverseMutationEffects函数
function recursivelyTraverseMutationEffects(
root,
parentFiber,
lanes,
) {
if (parentFiber.subtreeFlags & MutationMask) {
let child = parentFiber.child;
//有子节点递归向下
while (child !== null) {
commitMutationEffectsOnFiber(child, root, lanes);
child = child.sibling;
}
}
}
commitReconciliationEffects函数
function commitReconciliationEffects(finishedWork) {
const flags = finishedWork.flags;
//判断本节点是否有Placement副作用,有调commitPlacement把本节点插入到父节点
if (flags & Placement) {
commitPlacement(finishedWork);
finishedWork.flags &= ~Placement;
}
if (flags & Hydrating) {
finishedWork.flags &= ~Hydrating;
}
}
commitPlacement函数
function commitPlacement(finishedWork) {
const parentFiber = getHostParentFiber(finishedWork);
//根据父节点类型找到父节点原生元素,找到本节点前一个节点,在前一个节点后插入或直接在父节点下添加
switch (parentFiber.tag) {
case HostSingleton: {
if (supportsSingletons) {
const parent = parentFiber.stateNode;
const before = getHostSibling(finishedWork);
insertOrAppendPlacementNode(finishedWork, before, parent);
break;
}
}
case HostComponent: {
const parent = parentFiber.stateNode;
if (parentFiber.flags & ContentReset) {
resetTextContent(parent);
parentFiber.flags &= ~ContentReset;
}
const before = getHostSibling(finishedWork);
insertOrAppendPlacementNode(finishedWork, before, parent);
break;
}
case HostRoot:
case HostPortal: {
const parent = parentFiber.stateNode.containerInfo;
const before = getHostSibling(finishedWork);
insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
break;
}
}
}
备注:
本文为清晰展现出本文核心逻辑把粘贴的源码中参数校验、typescript类型、不相关逻辑等已删除