This article brings you a detailed analysis of ReactDom.render, which has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Steps
1. Create ReactRoot
2. Create FiberRoot and FiberRoot
3. Create Update
render method:
render( element: React$Element<any>, container: DOMContainer, callback: ?Function, ) { invariant( isValidContainer(container), 'Target container is not a DOM element.', ); return legacyRenderSubtreeIntoContainer( null, element, container, false, callback, ); },
The render method can pass in three parameters including ReactElement, the DOM wrapping node, and the callback method executed after rendering.
Then verify invariant
Verify whether the container is a valid Dom node.
Finally return the result after the legacyRenderSubtreeIntoContainer
method is executed. Let’s take a look at the parameters of this method.
function legacyRenderSubtreeIntoContainer( parentComponent: ?React$Component<any, any>, children: ReactNodeList, container: DOMContainer, forceHydrate: boolean, callback: ?Function, )
Five parameters are passed in here. The first one is that parentComponent does not exist and null is passed in. The second is the child element passed in the container, the third is the wrapping element that creates ReactRoot, the fourth is the option to coordinate updates, and the fifth is the callback method after rendering.
let root: Root = (container._reactRootContainer: any); if (!root) { // Initial mount root = container._reactRootContainer = legacyCreateRootFromDOMContainer( container, forceHydrate, );
First check whether ReactRoot exists and then execute the passed in container.
legacyCreateRootFromDOMContainerfunction after
forceHydrate creates a ReactRoot. The false passed in forceHydrate in the render method and the true passed in the Hydrate method are mainly to distinguish server-side rendering and client-side rendering. When true, the original node is not reused and is suitable for server-side rendering.
If it is false Then executecontainer.removeChild(rootSibling)
to delete all child nodes.
Then return throughnew ReactRoot(container, isConcurrent, shouldHydrate)
:
function ReactRoot( container: DOMContainer, isConcurrent: boolean, hydrate: boolean, ) { const root = createContainer(container, isConcurrent, hydrate); this._internalRoot = root; }
Call createContainer
in this method to create root, this method starts from react-reconciler/inline.dom
Introduced in the file:
export function createContainer( containerInfo: Container, isConcurrent: boolean, hydrate: boolean, ): OpaqueRoot { return createFiberRoot(containerInfo, isConcurrent, hydrate); }
In this method, the createFiberRoot
method is called to create FiberRoot
Executed after creating the root unbatchedUpdates
Update, pass in root. render method update:
unbatchedUpdates(() => { if (parentComponent != null) { root.legacy_renderSubtreeIntoContainer( parentComponent, children, callback, ); } else { root.render(children, callback); } });
Execute updateContainer(children, root, null, work._onCommit);
method, this method ultimately calls enqueueUpdate
and scheduleWork
, and returns expireTime, which performs scheduling algorithm and priority judgment
[Related recommendations: react video tutorial]
The above is the detailed content of Detailed analysis of ReactDom.render. For more information, please follow other related articles on the PHP Chinese website!