本文内容基于 React 17.0.0,主要在 legacy mode 下针对 React-reconciler 来进行分析
导读
React Diff 的过程发生在 beginWork 内,每个节点被 Diff 的时机基本上都是在其父节点状态更新快结束后发生的,其关键函数是一个叫 reconcileChildren 的函数。所以下文均会使用 reconcileChildren 来代指 Diff 的发生。
reconcileChildren 不会直接涉及子节点的状态更新,只是 创建新 Fiber、复用旧 Fiber 、找到需要删除的无用旧 Fiber,然后生成一个得到一个最新状态的第一个子节点的 Fiber,然后在下一个 workLoop 中进行更细节的节点状态更新等。
ReconcileChildren
函数签名
function reconcileChildFibers(
returnFiber: Fiber, // WIP 的 Fiber 节点
currentFirstChild: Fiber | null, // Current 节点的第一个子节点的 Fiber
newChild: any, // 最新的子节点的 ReactElement
lanes: Lanes, // 更新优先级,在本文中无需在意
): Fiber | null {}
逻辑流程图
小节
ReconcileChildren 主要会通过新的子节点的 ReactElement 类型来将逻辑分流,分别到其他自逻辑进行详细的 Diff,下面会进行一一的罗列。
reconcileSingleElement
reconcileSinglePortal
reconcileSingleTextNode
reconcileChildrenArray
reconcileChildrenIterator
迭代器的 reconciler 方式与 reconcileChildrenArray 基本一致,只不过遍历方式等做了一些区分,便不再赘述了。