1、Fiber定义

Fiber包含三层含义:

  • 作为架构来说,之前React15的Reconciler采用递归的方式执行,数据保存在递归调用栈中,所以被称为stack Reconciler。React16的Reconciler基于Fiber节点实现,被称为Fiber Reconciler。
  • 作为静态的数据结构来说,每个Fiber节点对应一个React element,保存了该组件的类型(函数组件/类组件/原生组件…)、对应的DOM节点等信息。
  • 作为动态的工作单元来说,每个Fiber节点保存了本次更新中该组件改变的状态、要执行的工作(需要被删除/被插入页面中/被更新…)。

React Fiber 机制的实现(作为架构),是依赖下面这种数据结构(链表),每一个节点都是一个fiber。一个 fiber 包括了 child(第一个子节点)、sibling(兄弟节点)、parent(父节点)属性。

image.png

2、fiber数据结构

主要有DOM、fiber树、状态数据、副作用四种标识;

  1. type Fiber = {
  2. /************************ DOM 实例相关 *****************************/
  3. // 作为静态数据
  4. // 标记不同的组件类型, 值详见 WorkTag
  5. tag: WorkTag,
  6. // 组件类型 div、span、组件构造函数
  7. type: any,
  8. // 实例对象, 如类组件的实例、原生 dom 实例, 而 function 组件没有实例, 因此该属性是空
  9. stateNode: any,
  10. /************************ 构建 Fiber 树相关 ***************************/
  11. // 作为架构
  12. // 指向自己的父级 Fiber 对象
  13. return: Fiber | null,
  14. // 指向自己的第一个子级 Fiber 对象
  15. child: Fiber | null,
  16. // 指向自己的下一个兄弟 iber 对象
  17. sibling: Fiber | null,
  18. // 在 Fiber 树更新的过程中,每个 Fiber 都会有一个跟其对应的 Fiber
  19. // 我们称他为 current <==> workInProgress
  20. // 在渲染完成之后他们会交换位置
  21. // alternate 指向当前 Fiber 在 workInProgress 树中的对应 Fiber
  22. alternate: Fiber | null,
  23. /************************ 状态数据相关 ********************************/
  24. // 作为动态工作单元
  25. // 即将更新的 props
  26. pendingProps: any,
  27. // 旧的 props
  28. memoizedProps: any,
  29. // 旧的 state
  30. memoizedState: any,
  31. /************************ 副作用相关 ******************************/
  32. // 该 Fiber 对应的组件产生的状态更新会存放在这个队列里面
  33. updateQueue: UpdateQueue<any> | null,
  34. // 用来记录当前 Fiber 要执行的 DOM 操作
  35. effectTag: SideEffectTag,
  36. // 存储第一个要执行副作用的子级 Fiber 对象
  37. firstEffect: Fiber | null,
  38. // 存储下一个要执行副作用的子级 Fiber 对象
  39. // 执行 DOM 渲染时要先通过 first 找到第一个, 然后通过 next 一直向后查找
  40. nextEffect: Fiber | null,
  41. // 存储 DOM 操作完后的副作用 比如调用生命周期函数或者钩子函数的调用
  42. lastEffect: Fiber | null,
  43. // 任务的过期时间
  44. expirationTime: ExpirationTime,
  45. // 当前组件及子组件处于何种渲染模式 详见 TypeOfMode
  46. mode: TypeOfMode,
  47. };

3、WorkTag

文件位置:packages/shared/ReactWorkTags.js

  1. type WorkTag =
  2. | 0
  3. | 1
  4. | 2
  5. | 3
  6. | 4
  7. | 5
  8. | 6
  9. | 7
  10. | 8
  11. | 9
  12. | 10
  13. | 11
  14. | 12
  15. | 13
  16. | 14
  17. | 15
  18. | 16
  19. | 17
  20. | 18
  21. | 19
  22. | 20
  23. | 21
  24. | 22;
  25. export const FunctionComponent = 0;
  26. export const ClassComponent = 1;
  27. export const IndeterminateComponent = 2;
  28. export const HostRoot = 3;
  29. export const HostPortal = 4;
  30. export const HostComponent = 5;
  31. export const HostText = 6;
  32. export const Fragment = 7;
  33. export const Mode = 8;
  34. export const ContextConsumer = 9;
  35. export const ContextProvider = 10;
  36. export const ForwardRef = 11;
  37. export const Profiler = 12;
  38. export const SuspenseComponent = 13;
  39. export const MemoComponent = 14;
  40. export const SimpleMemoComponent = 15;
  41. export const LazyComponent = 16;
  42. export const IncompleteClassComponent = 17;
  43. export const DehydratedFragment = 18;
  44. export const SuspenseListComponent = 19;
  45. export const FundamentalComponent = 20;
  46. export const ScopeComponent = 21;
  47. export const Block = 22;

4、TypeOfMode

文件位置: packages/react-reconciler/src/ReactTypeOfMode.js

  1. export type TypeOfMode = number;
  2. // 0 同步渲染模式
  3. export const NoMode = 0b0000;
  4. // 1 严格模式
  5. export const StrictMode = 0b0001;
  6. // 10 异步渲染过渡模式
  7. export const BlockingMode = 0b0010;
  8. // 100 异步渲染模式
  9. export const ConcurrentMode = 0b0100;
  10. // 1000 性能测试模式
  11. export const ProfileMode = 0b1000;

5、SideEffectTag

文件位置:packages/shared/ReactSideEffectTags.js

  1. export type SideEffectTag = number;
  2. // Don't change these two values. They're used by React Dev Tools.
  3. export const NoEffect = /* */ 0b0000000000000; // 0
  4. export const PerformedWork = /* */ 0b0000000000001; // 1
  5. // You can change the rest (and add more).
  6. export const Placement = /* */ 0b0000000000010; // 2
  7. export const Update = /* */ 0b0000000000100; // 4
  8. export const PlacementAndUpdate = /* */ 0b0000000000110; // 6
  9. export const Deletion = /* */ 0b0000000001000; // 8
  10. export const ContentReset = /* */ 0b0000000010000; // 16
  11. export const Callback = /* */ 0b0000000100000; // 32
  12. export const DidCapture = /* */ 0b0000001000000; // 64
  13. export const Ref = /* */ 0b0000010000000; // 128
  14. export const Snapshot = /* */ 0b0000100000000; // 256
  15. export const Passive = /* */ 0b0001000000000; // 512
  16. export const Hydrating = /* */ 0b0010000000000; // 1024
  17. export const HydratingAndUpdate = /* */ 0b0010000000100; // 1028
  18. // Passive & Update & Callback & Ref & Snapshot
  19. export const LifecycleEffectMask = /* */ 0b0001110100100; // 932
  20. // Union of all host effects
  21. export const HostEffectMask = /* */ 0b0011111111111; // 2047
  22. export const Incomplete = /* */ 0b0100000000000; // 2048
  23. export const ShouldCapture = /* */ 0b1000000000000; // 4096