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);
}