1. var FunctionComponent = 0; // Function 节点
  2. /*
  3. renderRoot // 主要的渲染都走这个。Diff
  4. workLoopSync
  5. performUnitOfWork
  6. beginWork$1 // 注意,这个方法有别名
  7. updateClassComponent
  8. mountClassInstance // 在此将ReactComponent初始化成Instance
  9. */
  10. var ClassComponent = 1; // Class节点
  11. var IndeterminateComponent = 2; // 在我们知道它是函数还是类之前
  12. var HostRoot = 3; // 宿主树的根。可以嵌套在另一个节点中。
  13. var HostPortal = 4; // 子树。可能是其他渲染器的入口点。
  14. var HostComponent = 5; // 主节点, <div> , <span> jsx节点
  15. var HostText = 6; // Text 节点
  16. /*
  17. function FnElement () {
  18. return <div>Element</div> // 这种类型的组件,是Fragment,而不是FunctionComponent
  19. }
  20. */
  21. var Fragment = 7;
  22. var Mode = 8;
  23. var ContextConsumer = 9;
  24. var ContextProvider = 10;
  25. var ForwardRef = 11;
  26. var Profiler = 12;
  27. var SuspenseComponent = 13;
  28. var MemoComponent = 14;
  29. var SimpleMemoComponent = 15;
  30. var LazyComponent = 16;
  31. var IncompleteClassComponent = 17;
  32. var DehydratedSuspenseComponent = 18;
  33. var SuspenseListComponent = 19;
  34. var FundamentalComponent = 20;
  1. function FiberNode(tag, pendingProps, key, mode) {
  2. // Instance
  3. // tag 标记了,当前节点的类型。
  4. this.tag = tag;
  5. // 标记索引
  6. this.key = key;
  7. // 如果tag = 1 是 class节点 elementType: ƒ ParentDom(props)
  8. // 如果tag = 5 是 host节点 elementType: "div"
  9. // 如果tag = 3 是 root节点 elementType: null
  10. // 如果tag = 6 是 root节点 elementType: null
  11. this.elementType = null;
  12. // type 与 elementType的值一样。
  13. this.type = null;
  14. // class 组件是 组件的实例
  15. // host 组件是 真实dom节点
  16. // text 组件是 null
  17. // root 组件是 FiberRootNode
  18. this.stateNode = null;
  19. // Fiber
  20. // 父节点
  21. this.return = null;
  22. // 子节点的首个节点
  23. this.child = null;
  24. // 下一个节点
  25. this.sibling = null;
  26. // 节点处于children位置的下标
  27. this.index = 0;
  28. // 组件的实例
  29. this.ref = null;
  30. this.pendingProps = pendingProps;
  31. this.memoizedProps = null;
  32. this.updateQueue = null;
  33. // 带有记忆的State,可以理解成,计算后的最新state状态保存在此属性中,完成后,将他交给实例
  34. // instance.state = workInProgress.memoizedState;
  35. this.memoizedState = null;
  36. this.dependencies = null;
  37. this.mode = mode;
  38. // Effects
  39. this.effectTag = NoEffect;
  40. // nextEffect 记录了当前是修改状态还是删除状态
  41. // nextEffect: {effectTag: 2 | 4 | 6 }
  42. this.nextEffect = null;
  43. this.firstEffect = null;
  44. this.lastEffect = null;
  45. this.expirationTime = NoWork;
  46. this.childExpirationTime = NoWork;
  47. this.alternate = null;
  48. if (enableProfilerTimer) {
  49. // Note: The following is done to avoid a v8 performance cliff.
  50. //
  51. // Initializing the fields below to smis and later updating them with
  52. // double values will cause Fibers to end up having separate shapes.
  53. // This behavior/bug has something to do with Object.preventExtension().
  54. // Fortunately this only impacts DEV builds.
  55. // Unfortunately it makes React unusably slow for some applications.
  56. // To work around this, initialize the fields below with doubles.
  57. //
  58. // Learn more about this here:
  59. // https://github.com/facebook/react/issues/14365
  60. // https://bugs.chromium.org/p/v8/issues/detail?id=8538
  61. this.actualDuration = Number.NaN;
  62. this.actualStartTime = Number.NaN;
  63. this.selfBaseDuration = Number.NaN;
  64. this.treeBaseDuration = Number.NaN;
  65. // It's okay to replace the initial doubles with smis after initialization.
  66. // This won't trigger the performance cliff mentioned above,
  67. // and it simplifies other profiler code (including DevTools).
  68. this.actualDuration = 0;
  69. this.actualStartTime = -1;
  70. this.selfBaseDuration = 0;
  71. this.treeBaseDuration = 0;
  72. }
  73. {
  74. this._debugID = debugCounter++;
  75. this._debugSource = null;
  76. this._debugOwner = null;
  77. this._debugIsCurrentlyTiming = false;
  78. this._debugNeedsRemount = false;
  79. this._debugHookTypes = null;
  80. if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
  81. Object.preventExtensions(this);
  82. }
  83. }
  84. }

根节点

  1. function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
  2. ...
  3. switch () {
  4. case HostRoot:
  5. // 返回根节点的首个节点
  6. return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
  7. }
  8. ...
  9. }

case HostRoot:
return updateHostRoot(current$$1, workInProgress, renderExpirationTime);