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, 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 verifyinvariant
Verify whether the container is a valid Dom node.
Finally return the result after thelegacyRenderSubtreeIntoContainer
method is executed. Let’s take a look at the parameters of this method.
function legacyRenderSubtreeIntoContainer( parentComponent: ?React$Component, 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; }
CallcreateContainer
in this method to create root, this method starts fromreact-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, thecreateFiberRoot
method is called to create FiberRoot
Executed after creating the rootunbatchedUpdates
Update, pass in root. render method update:
unbatchedUpdates(() => { if (parentComponent != null) { root.legacy_renderSubtreeIntoContainer( parentComponent, children, callback, ); } else { root.render(children, callback); } });
ExecuteupdateContainer(children, root, null, work._onCommit);
method, this method ultimately callsenqueueUpdate
andscheduleWork
, 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!