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 实例相关 *****************************/
// 作为静态数据
// 标记不同的组件类型, 值详见 WorkTag
tag: 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 树中的对应 Fiber
alternate: Fiber | null,
/************************ 状态数据相关 ********************************/
// 作为动态工作单元
// 即将更新的 props
pendingProps: any,
// 旧的 props
memoizedProps: any,
// 旧的 state
memoizedState: 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,
// 当前组件及子组件处于何种渲染模式 详见 TypeOfMode
mode: 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; // 0
export const PerformedWork = /* */ 0b0000000000001; // 1
// You can change the rest (and add more).
export const Placement = /* */ 0b0000000000010; // 2
export const Update = /* */ 0b0000000000100; // 4
export const PlacementAndUpdate = /* */ 0b0000000000110; // 6
export const Deletion = /* */ 0b0000000001000; // 8
export const ContentReset = /* */ 0b0000000010000; // 16
export const Callback = /* */ 0b0000000100000; // 32
export const DidCapture = /* */ 0b0000001000000; // 64
export const Ref = /* */ 0b0000010000000; // 128
export const Snapshot = /* */ 0b0000100000000; // 256
export const Passive = /* */ 0b0001000000000; // 512
export const Hydrating = /* */ 0b0010000000000; // 1024
export const HydratingAndUpdate = /* */ 0b0010000000100; // 1028
// Passive & Update & Callback & Ref & Snapshot
export const LifecycleEffectMask = /* */ 0b0001110100100; // 932
// Union of all host effects
export const HostEffectMask = /* */ 0b0011111111111; // 2047
export const Incomplete = /* */ 0b0100000000000; // 2048
export const ShouldCapture = /* */ 0b1000000000000; // 4096