1、逻辑分层
- scheduleUpdateOnFiber方法为调度更新
- performSyncWorkOnRoot为开启render阶段(render阶段)
commitRoot为真实Dom渲染过程(commit阶段)
ReactDOM.render可以我分为三个阶段:
初始化主要干的事就是完成 Fiber 树中基本实体的创建,具体请移步查看源码阅读篇。
八、render阶段
2.1 主体逻辑链路
主要逻辑代码如下:
function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {// container 对应的是我们传入的真实 DOM 对象var root = container._reactRootContainer;// 初始化 fiberRoot 对象var fiberRoot;// DOM 对象本身不存在 _reactRootContainer 属性,因此 root 为空if (!root) {// 若 root 为空,则初始化 _reactRootContainer,并将其值赋值给 rootroot = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);// legacyCreateRootFromDOMContainer 创建出的对象会有一个 _internalRoot 属性,将其赋值给 fiberRootfiberRoot = root._internalRoot;// 这里处理的是 ReactDOM.render 入参中的回调函数,你了解即可if (typeof callback === 'function') {// ...省略}// 进入 unbatchedUpdates 方法unbatchedUpdates(function () {updateContainer(children, fiberRoot, parentComponent, callback);});} else {// ...省略updateContainer(children, fiberRoot, parentComponent, callback);}return getPublicRootInstance(fiberRoot);}
上面代码主要逻辑链路:
2.2 root拆解:

这段代码其实就是做了这件事:
- 创建 FiberRoot 和 rootFiber
- fiberRoot的current属性指向rootFiber,
- rootFiber的stateNode属性执行fiberRoot

fiberRoot 的关联对象是真实 DOM 的容器节点;而 rootFiber 则作为虚拟 DOM 的根节点存在。这两个节点,将是后续整棵 Fiber 树构建的起点。
2.3 unbatchedUpdates方法拆解:
unbatchedUpdates(function () {updateContainer(children, fiberRoot, parentComponent, callback);});
unbatchedUpdates方法:
function unbatchedUpdates(fn, a) {// ...省略...try {// 重点在这里,直接调用了传入的回调函数 fn,对应当前链路中的 updateContainer 方法return fn(a);} finally {// ...省略...}}
updateContainer方法:
function updateContainer(element, container, parentComponent, callback) {......// 这是一个 event 相关的入参,此处不必关注var eventTime = requestEventTime();......// 这是一个比较关键的入参,lane 表示优先级var lane = requestUpdateLane(current$1);// 结合 lane(优先级)信息,创建 update 对象,一个 update 对象意味着一个更新var update = createUpdate(eventTime, lane);// update 的 payload 对应的是一个 React 元素update.payload = {element: element};// 处理 callback,这个 callback 其实就是我们调用 ReactDOM.render 时传入的 callbackcallback = callback === undefined ? null : callback;if (callback !== null) {{if (typeof callback !== 'function') {error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);}}update.callback = callback;}// 将 update 入队enqueueUpdate(current$1, update);// 调度 fiberRootscheduleUpdateOnFiber(current$1, lane, eventTime);// 返回当前节点(fiberRoot)的优先级return lane;}
updateContainer最关键的事情可以总结为三件:
ReactDOM.render(
- blocking 模式:
ReactDOM.createBlockingRoot(rootNode).render(
- concurrent 模式:
ReactDOM.createRoot(rootNode).render(
我们目前常用的 ReactDOM.render 对应的是 legacy 模式,它实际触发的仍然是同步的渲染链路。
同步的 ReactDOM.render,异步的ReactDOM.createRoot。
