Appearance
一个DOM节点在某一时刻最多会有 4个 节点和他相关。
current Fiber。如果该DOM节点已在页面中,current Fiber代表该DOM节点对应的Fiber节点。workInProgress Fiber。如果该DOM节点将在本次更新中渲染到页面中,workInProgress Fiber代表该DOM节点对应的Fiber节点。DOM节点本身。JSX对象。即ClassComponent的render方法的返回结果,或FunctionComponent的调用结果。JSX对象中包含描述DOM节点的信息。Diff算法的本质是对比1和4,生成2。
Diff 算法入口
在 reconcileChildren 过程中 调用 的 reconcileChildFibers
js
// packages/react-reconciles/src/ReactChildFiber.js
function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
//...
const isObject = typeof newChild === 'object' && newChild !== null;
if (isObject) {
// object类型,可能是 REACT_ELEMENT_TYPE 或 REACT_PORTAL_TYPE
switch (newChild.$$typeof) {
// 新 jsx对象的 类型
case REACT_ELEMENT_TYPE:
// 单个子节点
// 调用 reconcileSingleElement 处理
return placeSingleChild(
reconcileSingleElement(
returnFiber,
currentFirstChild,
newChild,
lanes,
),
);
}
if (isArray(newChild)) {
// 多个子节点 调用 reconcileChildrenArray 处理
return reconcileChildrenArray(
returnFiber,
currentFirstChild,
newChild,
lanes,
);
}
}
if (typeof newChild === 'string' || typeof newChild === 'number') {
// 文本 调用 reconcileSingleTextNode 处理
return placeSingleChild(
reconcileSingleTextNode(
returnFiber,
currentFirstChild,
'' + newChild,
lanes,
),
);
}
// 一些其他情况调用处理函数
// 以上都没有命中,删除节点
return deleteRemainingChildren(returnFiber, currentFirstChild);
}