Fiber节点的结构
路径:react-reconciler/src/ReacFiber.old.js
fiber节点主要包含四部分的数据:静态节点相关、Fiber树结构相关、更新状态相关、调度优先级相关
function FiberNode(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// 静态节点相关属性,与react element对应
this.tag = tag; // 组件类型 Host、Function、Class等
this.key = key;
this.elementType = null;
this.type = null; // Host是DOM节点的tagName,Function是函数自身,Class是class...
this.stateNode = null; // 对应的DOM节点
// Fiber树结构相关的属性
this.return = null; // 父fiber节点(绝大多数情况下),或是上次中断后,需要恢复执行的节点
this.child = null; // 第一个fiber子节点
this.sibling = null; // 第一个兄弟fiber节点
this.index = 0;
this.ref = null;
// 更新状态相关属性
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;
// Effects
this.flags = NoFlags;
this.nextEffect = null;
this.firstEffect = null;
this.lastEffect = null;
// 调度优先级相关
this.lanes = NoLanes;
this.childLanes = NoLanes;
// 更新时,另一颗fiber树上对应该节点的fiber节点
this.alternate = null;
}
Fiber不仅是对于原生DOM的一种虚拟DOM的表现形式。它还保存了更新状态和调度相关的信息,是react更新机制的动态的工作单元
工作流程
先抛开调度的机制,看源码中从Fiber到最终渲染到页面上的基本流程
Render阶段
在react-reconciler/src/ReactFiberWorkLoop.old.js中,会判断是否有需要执行的任务(workInProgress),如果有就调用performUnitOfWork。它接收当前需要执行的Fiber。主要代码如下:
function performUnitOfWork(unitOfWork: Fiber): void {
const current = unitOfWork.alternate;
let next;
// ...省略部分代码
next = beginWork(current, unitOfWork, subtreeRenderLanes);
// ...省略部分代码
unitOfWork.memoizedProps = unitOfWork.pendingProps;
if (next === null) {
completeUnitOfWork(unitOfWork);
} else {
workInProgress = next;
}
ReactCurrentOwner.current = null;
}
performUnitOfWork以深度优先遍历的方式,对各节点主要做了四件事,最终得到需要修改的虚拟DOM:
- 将当前的操作节点,换成与当前Fiber对应的更新的Fiber节点(双缓存Fiber树机制)
- 当前节点执行beginWork,返回当前节点的下一个节点
- 更改当前节点属性的状态
- 判断是否还有需要处理的节点,如果没有则调用completeUnitOfWork,如果有则继续循环操作下一个节点
commit阶段
遍历完所有节点后,进入Renderer的部分,commit阶段,react-reconciler/src/ReactFiberWorkLoop.old.js下的commitRoot方法。其主要调用了commitRootImpl,该方法很长,拆分一下主要分为五个部分,不同阶段都会对应执行一些生命周期的钩子,DOM节点的相关操作,以及Hooks的调度:
- before mutation前
- before mutation
- mutation
- layout
- layout后
总结
Fiber的大体流程是通过调度器(Scheduler)将任务交给协调器(Reconciler),协调器遍历处理所有任务,得到需要修改的虚拟DOM。然后交给Renderer(渲染器)进行DOM操作。
接下来会详细去看Render阶段的beginWork和completeWork,commit的各阶段的工作。了解了整个流程后,再看scheduler的调度机制。