Appearance
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