Skip to content

ReactDOM.render()

legacyRenderSubtreeIntoContainer

js
function legacyRenderSubtreeIntoContainer(
  parentComponent: ?React$Component<any, any>,
  children: ReactNodeList,
  container: Container,
  forceHydrate: boolean,
  callback: ?Function,
) {
  // TODO: Without `any` type, Flow says "Property cannot be accessed on any
  // member of intersection type." Whyyyyyy.
  let root: RootType = (container._reactRootContainer: any);
  let fiberRoot;
  if (!root) {
    // Initial mount
    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
      container,
      forceHydrate,
    );
    fiberRoot = root._internalRoot;
    if (typeof callback === 'function') {
      const originalCallback = callback;
      callback = function() {
        const instance = getPublicRootInstance(fiberRoot);
        originalCallback.call(instance);
      };
    }
    // Initial mount should not be batched.
    // 初始渲染 不执行批量更新,需要尽快渲染并不能被打断
    unbatchedUpdates(() => {
      updateContainer(children, fiberRoot, parentComponent, callback);
    });
  } else {
    fiberRoot = root._internalRoot;
    if (typeof callback === 'function') {
      const originalCallback = callback;
      callback = function() {
        const instance = getPublicRootInstance(fiberRoot);
        originalCallback.call(instance);
      };
    }
    // Update
    updateContainer(children, fiberRoot, parentComponent, callback);
  }
  return getPublicRootInstance(fiberRoot);
}

其主要流程是两个: 1. 创建 FiberRoot 和 FiberNode(Root) 2. updateContainer()

legacyCreateRootFromDOMContainer(container, forceHydrate)

通过 legacyCreateRootFromDOMContainer()的流程可以发现,其也是我们在react18的时候将ReactDOM.render(<App />,dom) -> ReactDOM.createRoot(dom).render(<App />)的流程,其也是通过 createLegacyRoot() -> new ReactDOMBlockingRoot()的过程去创建一个 OpaqueRoot