FiberRoot

  1. type BaseFiberRootProperties = {|
  2. // root节点,render方法接收的第二个参数
  3. containerInfo: any,
  4. // 只有在持久更新中会用到,也就是不支持增量更新的平台,react-dom不会用到
  5. pendingChildren: any,
  6. // 当前应用对应的Fiber对象,是Root Fiber
  7. current: Fiber,
  8. // 一下的优先级是用来区分
  9. // 1) 没有提交(committed)的任务
  10. // 2) 没有提交的挂起任务
  11. // 3) 没有提交的可能被挂起的任务
  12. // 我们选择不追踪每个单独的阻塞登记,为了兼顾性能
  13. // The earliest and latest priority levels that are suspended from committing.
  14. // 最老和新的在提交的时候被挂起的任务
  15. earliestSuspendedTime: ExpirationTime,
  16. latestSuspendedTime: ExpirationTime,
  17. // The earliest and latest priority levels that are not known to be suspended.
  18. // 最老和最新的不确定是否会挂起的优先级(所有任务进来一开始都是这个状态)
  19. earliestPendingTime: ExpirationTime,
  20. latestPendingTime: ExpirationTime,
  21. // The latest priority level that was pinged by a resolved promise and can
  22. // be retried.
  23. // 最新的通过一个promise被reslove并且可以重新尝试的优先级
  24. latestPingedTime: ExpirationTime,
  25. // 如果有错误被抛出并且没有更多的更新存在,我们尝试在处理错误前同步重新从头渲染
  26. // 在`renderRoot`出现无法处理的错误时会被设置为`true`
  27. didError: boolean,
  28. // 正在等待提交的任务的`expirationTime`
  29. pendingCommitExpirationTime: ExpirationTime,
  30. // 已经完成的任务的FiberRoot对象,如果你只有一个Root,那他永远只可能是这个Root对应的Fiber,或者是null
  31. // 在commit阶段只会处理这个值对应的任务
  32. finishedWork: Fiber | null,
  33. // 在任务被挂起的时候通过setTimeout设置的返回内容,用来下一次如果有新的任务挂起时清理还没触发的timeout
  34. timeoutHandle: TimeoutHandle | NoTimeout,
  35. // 顶层context对象,只有主动调用`renderSubtreeIntoContainer`时才会有用
  36. context: Object | null,
  37. pendingContext: Object | null,
  38. // 用来确定第一次渲染的时候是否需要融合
  39. +hydrate: boolean,
  40. // 当前root上剩余的过期时间
  41. // TODO: 提到renderer里面区处理
  42. nextExpirationTimeToWorkOn: ExpirationTime,
  43. // 当前更新对应的过期时间
  44. expirationTime: ExpirationTime,
  45. // List of top-level batches. This list indicates whether a commit should be
  46. // deferred. Also contains completion callbacks.
  47. // TODO: Lift this into the renderer
  48. // 顶层批次(批处理任务?)这个变量指明一个commit是否应该被推迟
  49. // 同时包括完成之后的回调
  50. // 貌似用在测试的时候?
  51. firstBatch: Batch | null,
  52. // root之间关联的链表结构
  53. nextScheduledRoot: FiberRoot | null,
  54. |};

Fiber

  1. // Fiber对应一个组件需要被处理或者已经处理了,一个组件可以有一个或者多个Fiber
  2. type Fiber = {|
  3. // 标记不同的组件类型
  4. tag: WorkTag,
  5. // ReactElement里面的key
  6. key: null | string,
  7. // ReactElement.type,也就是我们调用`createElement`的第一个参数
  8. elementType: any,
  9. // The resolved function/class/ associated with this fiber.
  10. // 异步组件resolved之后返回的内容,一般是`function`或者`class`
  11. type: any,
  12. // The local state associated with this fiber.
  13. // 跟当前Fiber相关本地状态(比如浏览器环境就是DOM节点)
  14. stateNode: any,
  15. // 指向他在Fiber节点树中的`parent`,用来在处理完这个节点之后向上返回
  16. return: Fiber | null,
  17. // 单链表树结构
  18. // 指向自己的第一个子节点
  19. child: Fiber | null,
  20. // 指向自己的兄弟结构
  21. // 兄弟节点的return指向同一个父节点
  22. sibling: Fiber | null,
  23. index: number,
  24. // ref属性
  25. ref: null | (((handle: mixed) => void) & {_stringRef: ?string}) | RefObject,
  26. // 新的变动带来的新的props
  27. pendingProps: any,
  28. // 上一次渲染完成之后的props
  29. memoizedProps: any,
  30. // 该Fiber对应的组件产生的Update会存放在这个队列里面
  31. updateQueue: UpdateQueue<any> | null,
  32. // 上一次渲染的时候的state
  33. memoizedState: any,
  34. // 一个列表,存放这个Fiber依赖的context
  35. firstContextDependency: ContextDependency<mixed> | null,
  36. // 用来描述当前Fiber和他子树的`Bitfield`
  37. // 共存的模式表示这个子树是否默认是异步渲染的
  38. // Fiber被创建的时候他会继承父Fiber
  39. // 其他的标识也可以在创建的时候被设置
  40. // 但是在创建之后不应该再被修改,特别是他的子Fiber创建之前
  41. mode: TypeOfMode,
  42. // Effect
  43. // 用来记录Side Effect
  44. effectTag: SideEffectTag,
  45. // 单链表用来快速查找下一个side effect
  46. nextEffect: Fiber | null,
  47. // 子树中第一个side effect
  48. firstEffect: Fiber | null,
  49. // 子树中最后一个side effect
  50. lastEffect: Fiber | null,
  51. // 代表任务在未来的哪个时间点应该被完成
  52. // 不包括他的子树产生的任务
  53. expirationTime: ExpirationTime,
  54. // 快速确定子树中是否有不在等待的变化
  55. childExpirationTime: ExpirationTime,
  56. // 在Fiber树更新的过程中,每个Fiber都会有一个跟其对应的Fiber
  57. // 我们称他为`current <==> workInProgress`
  58. // 在渲染完成之后他们会交换位置
  59. alternate: Fiber | null,
  60. // 下面是调试相关的,收集每个Fiber和子树渲染时间的
  61. actualDuration?: number,
  62. // If the Fiber is currently active in the "render" phase,
  63. // This marks the time at which the work began.
  64. // This field is only set when the enableProfilerTimer flag is enabled.
  65. actualStartTime?: number,
  66. // Duration of the most recent render time for this Fiber.
  67. // This value is not updated when we bailout for memoization purposes.
  68. // This field is only set when the enableProfilerTimer flag is enabled.
  69. selfBaseDuration?: number,
  70. // Sum of base times for all descedents of this Fiber.
  71. // This value bubbles up during the "complete" phase.
  72. // This field is only set when the enableProfilerTimer flag is enabled.
  73. treeBaseDuration?: number,
  74. // Conceptual aliases
  75. // workInProgress : Fiber -> alternate The alternate used for reuse happens
  76. // to be the same as work in progress.
  77. // __DEV__ only
  78. _debugID?: number,
  79. _debugSource?: Source | null,
  80. _debugOwner?: Fiber | null,
  81. _debugIsCurrentlyTiming?: boolean,
  82. |};

effectTags

  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow
  8. */
  9. export type SideEffectTag = number;
  10. // Don't change these two values. They're used by React Dev Tools.
  11. export const NoEffect = /* */ 0b00000000000;
  12. export const PerformedWork = /* */ 0b00000000001;
  13. // You can change the rest (and add more).
  14. export const Placement = /* */ 0b00000000010;
  15. export const Update = /* */ 0b00000000100;
  16. export const PlacementAndUpdate = /* */ 0b00000000110;
  17. export const Deletion = /* */ 0b00000001000;
  18. export const ContentReset = /* */ 0b00000010000;
  19. export const Callback = /* */ 0b00000100000;
  20. export const DidCapture = /* */ 0b00001000000;
  21. export const Ref = /* */ 0b00010000000;
  22. export const Snapshot = /* */ 0b00100000000;
  23. // Update & Callback & Ref & Snapshot
  24. export const LifecycleEffectMask = /* */ 0b00110100100;
  25. // Union of all host effects
  26. export const HostEffectMask = /* */ 0b00111111111;
  27. export const Incomplete = /* */ 0b01000000000;
  28. export const ShouldCapture = /* */ 0b10000000000;

ReactWorkTag

  1. export const FunctionComponent = 0;
  2. export const ClassComponent = 1;
  3. export const IndeterminateComponent = 2; // Before we know whether it is function or class
  4. export const HostRoot = 3; // Root of a host tree. Could be nested inside another node.
  5. export const HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
  6. export const HostComponent = 5;
  7. export const HostText = 6;
  8. export const Fragment = 7;
  9. export const Mode = 8;
  10. export const ContextConsumer = 9;
  11. export const ContextProvider = 10;
  12. export const ForwardRef = 11;
  13. export const Profiler = 12;
  14. export const SuspenseComponent = 13;
  15. export const MemoComponent = 14;
  16. export const SimpleMemoComponent = 15;
  17. export const LazyComponent = 16;
  18. export const IncompleteClassComponent = 17;

sideEffects

  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow
  8. */
  9. export type SideEffectTag = number;
  10. // Don't change these two values. They're used by React Dev Tools.
  11. export const NoEffect = /* */ 0b00000000000;
  12. export const PerformedWork = /* */ 0b00000000001;
  13. // You can change the rest (and add more).
  14. export const Placement = /* */ 0b00000000010;
  15. export const Update = /* */ 0b00000000100;
  16. export const PlacementAndUpdate = /* */ 0b00000000110;
  17. export const Deletion = /* */ 0b00000001000;
  18. export const ContentReset = /* */ 0b00000010000;
  19. export const Callback = /* */ 0b00000100000;
  20. export const DidCapture = /* */ 0b00001000000;
  21. export const Ref = /* */ 0b00010000000;
  22. export const Snapshot = /* */ 0b00100000000;
  23. // Update & Callback & Ref & Snapshot
  24. export const LifecycleEffectMask = /* */ 0b00110100100;
  25. // Union of all host effects
  26. export const HostEffectMask = /* */ 0b00111111111;
  27. export const Incomplete = /* */ 0b01000000000;
  28. export const ShouldCapture = /* */ 0b10000000000;

Update & UpdateQueue

  1. export type Update<State> = {
  2. // 更新的过期时间
  3. expirationTime: ExpirationTime,
  4. // export const UpdateState = 0;
  5. // export const ReplaceState = 1;
  6. // export const ForceUpdate = 2;
  7. // export const CaptureUpdate = 3;
  8. // 指定更新的类型,值为以上几种
  9. tag: 0 | 1 | 2 | 3,
  10. // 更新内容,比如`setState`接收的第一个参数
  11. payload: any,
  12. // 对应的回调,`setState`,`render`都有
  13. callback: (() => mixed) | null,
  14. // 指向下一个更新
  15. next: Update<State> | null,
  16. // 指向下一个`side effect`
  17. nextEffect: Update<State> | null,
  18. };
  19. export type UpdateQueue<State> = {
  20. // 每次操作完更新之后的`state`
  21. baseState: State,
  22. // 队列中的第一个`Update`
  23. firstUpdate: Update<State> | null,
  24. // 队列中的最后一个`Update`
  25. lastUpdate: Update<State> | null,
  26. // 第一个捕获类型的`Update`
  27. firstCapturedUpdate: Update<State> | null,
  28. // 最后一个捕获类型的`Update`
  29. lastCapturedUpdate: Update<State> | null,
  30. // 第一个`side effect`
  31. firstEffect: Update<State> | null,
  32. // 最后一个`side effect`
  33. lastEffect: Update<State> | null,
  34. // 第一个和最后一个捕获产生的`side effect`
  35. firstCapturedEffect: Update<State> | null,
  36. lastCapturedEffect: Update<State> | null,
  37. };