1、Fiber定义
Fiber包含三层含义:
- 作为架构来说,之前React15的Reconciler采用递归的方式执行,数据保存在递归调用栈中,所以被称为stack Reconciler。React16的Reconciler基于Fiber节点实现,被称为Fiber Reconciler。
- 作为静态的数据结构来说,每个Fiber节点对应一个React element,保存了该组件的类型(函数组件/类组件/原生组件…)、对应的DOM节点等信息。
- 作为动态的工作单元来说,每个Fiber节点保存了本次更新中该组件改变的状态、要执行的工作(需要被删除/被插入页面中/被更新…)。
React Fiber 机制的实现(作为架构),是依赖下面这种数据结构(链表),每一个节点都是一个fiber。一个 fiber 包括了 child(第一个子节点)、sibling(兄弟节点)、parent(父节点)属性。

2、fiber数据结构
主要有DOM、fiber树、状态数据、副作用四种标识;
type Fiber = {/************************ DOM 实例相关 *****************************/// 作为静态数据// 标记不同的组件类型, 值详见 WorkTagtag: WorkTag,// 组件类型 div、span、组件构造函数type: any,// 实例对象, 如类组件的实例、原生 dom 实例, 而 function 组件没有实例, 因此该属性是空stateNode: any,/************************ 构建 Fiber 树相关 ***************************/// 作为架构// 指向自己的父级 Fiber 对象return: Fiber | null,// 指向自己的第一个子级 Fiber 对象child: Fiber | null,// 指向自己的下一个兄弟 iber 对象sibling: Fiber | null,// 在 Fiber 树更新的过程中,每个 Fiber 都会有一个跟其对应的 Fiber// 我们称他为 current <==> workInProgress// 在渲染完成之后他们会交换位置// alternate 指向当前 Fiber 在 workInProgress 树中的对应 Fiberalternate: Fiber | null,/************************ 状态数据相关 ********************************/// 作为动态工作单元// 即将更新的 propspendingProps: any,// 旧的 propsmemoizedProps: any,// 旧的 statememoizedState: any,/************************ 副作用相关 ******************************/// 该 Fiber 对应的组件产生的状态更新会存放在这个队列里面updateQueue: UpdateQueue<any> | null,// 用来记录当前 Fiber 要执行的 DOM 操作effectTag: SideEffectTag,// 存储第一个要执行副作用的子级 Fiber 对象firstEffect: Fiber | null,// 存储下一个要执行副作用的子级 Fiber 对象// 执行 DOM 渲染时要先通过 first 找到第一个, 然后通过 next 一直向后查找nextEffect: Fiber | null,// 存储 DOM 操作完后的副作用 比如调用生命周期函数或者钩子函数的调用lastEffect: Fiber | null,// 任务的过期时间expirationTime: ExpirationTime,// 当前组件及子组件处于何种渲染模式 详见 TypeOfModemode: TypeOfMode,};
3、WorkTag
文件位置:packages/shared/ReactWorkTags.js
type WorkTag =| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22;export const FunctionComponent = 0;export const ClassComponent = 1;export const IndeterminateComponent = 2;export const HostRoot = 3;export const HostPortal = 4;export const HostComponent = 5;export const HostText = 6;export const Fragment = 7;export const Mode = 8;export const ContextConsumer = 9;export const ContextProvider = 10;export const ForwardRef = 11;export const Profiler = 12;export const SuspenseComponent = 13;export const MemoComponent = 14;export const SimpleMemoComponent = 15;export const LazyComponent = 16;export const IncompleteClassComponent = 17;export const DehydratedFragment = 18;export const SuspenseListComponent = 19;export const FundamentalComponent = 20;export const ScopeComponent = 21;export const Block = 22;
4、TypeOfMode
文件位置: packages/react-reconciler/src/ReactTypeOfMode.js
export type TypeOfMode = number;// 0 同步渲染模式export const NoMode = 0b0000;// 1 严格模式export const StrictMode = 0b0001;// 10 异步渲染过渡模式export const BlockingMode = 0b0010;// 100 异步渲染模式export const ConcurrentMode = 0b0100;// 1000 性能测试模式export const ProfileMode = 0b1000;
5、SideEffectTag
文件位置:packages/shared/ReactSideEffectTags.js
export type SideEffectTag = number;// Don't change these two values. They're used by React Dev Tools.export const NoEffect = /* */ 0b0000000000000; // 0export const PerformedWork = /* */ 0b0000000000001; // 1// You can change the rest (and add more).export const Placement = /* */ 0b0000000000010; // 2export const Update = /* */ 0b0000000000100; // 4export const PlacementAndUpdate = /* */ 0b0000000000110; // 6export const Deletion = /* */ 0b0000000001000; // 8export const ContentReset = /* */ 0b0000000010000; // 16export const Callback = /* */ 0b0000000100000; // 32export const DidCapture = /* */ 0b0000001000000; // 64export const Ref = /* */ 0b0000010000000; // 128export const Snapshot = /* */ 0b0000100000000; // 256export const Passive = /* */ 0b0001000000000; // 512export const Hydrating = /* */ 0b0010000000000; // 1024export const HydratingAndUpdate = /* */ 0b0010000000100; // 1028// Passive & Update & Callback & Ref & Snapshotexport const LifecycleEffectMask = /* */ 0b0001110100100; // 932// Union of all host effectsexport const HostEffectMask = /* */ 0b0011111111111; // 2047export const Incomplete = /* */ 0b0100000000000; // 2048export const ShouldCapture = /* */ 0b1000000000000; // 4096
