- createRoot 函数最终会返回一个 new ReactDOMRoot 的实例,而在 ReactDOMRoot 函数中会调用 createRootImpl - ReactDOMRoot 主要任务是给实例上的 \_internalRoot 属性赋值 - createRootImpl 函数接收三个参数,第一个是 React 开始渲染的根节点 DOM 元素,对应 createRoot 函数的第一个参数,而第二个是当前 React 的调度模式,第三个参数是 createRoot 第二个参数 options。 - 调度模式 RootTag: 1. LegacyRoot:0 2. BlockingRoot:1 3. ConcurrentRoot:2 - 由 createRootImpl 调用 createContainer,接受 DOM 元素 和 RootTag 参数,后两个和 SSR 相关,createContainer 主要任务是调用 createFiberRoot 函数,传递的参数和 createContainer 相同 - 在 createFiberRoot 函数内部会 new FiberRootNode 创建 FiberRootNode 节点,紧接着会调用 createHostRootFiber 并传递 RootTag 创建第一个 Fiber 节点即 rootFiber,这个 rootFiber 就是 WorkInProgress 树的第一个节点 - createFiber 函数接受三个参数,分别是 Fiber 类型、Fiber props、key 和 mode,其中 mode 参数似乎和 RootTag 有关,最终会 new FiberNode 并返回 - [[Fiber 数据结构]]中有个 index 属性,这个属性记录的是当前节点在同级兄弟节点当中的位置索引,diff 时会和 key 一起做比较,也就是说,如果组件不给 key 属性,实际上 Fiber 节点也会自带一个 index 属性 - createHostRootFiber 创建完 FiberRootNode 和 rootFiber 回到 createFiberRoot 调用栈,会将创建的 FiberRootNode 的 current 属性指向刚创建的 rootFiber,即 React 双缓存机制的开始,并将 rootFiber 的 stateNode 属性赋值为 FiberRootNode,同时调用 initializeUpdateQueue 初始化 rootFiber 的 updateQueue 属性,最后返回结束 createFiberRoot 调用栈返回 FiberRootNode 回到 createContainer 再回到 createRootImpl,接着执行 markContainerAsRoot 函数 - markContainerAsRoot 函数的任务很简单,它会在根节点 DOM 元素上添加一个属性并赋值为 rootFiber - createRootImpl 结束后会回到 createRoot 调用栈,并返回创建的 FiberRootNode,最终进入到 jsx 方法中去