Reactdom. render function call description
Here only discuss web side first invocation of hydrate all default to false | undefinde, without explanationCopy the code
ReactDOM.render(element,container,callback)
- element reactElemtn
- container HtmlElemnt
- Callback Callback after the mount is complete
Effect: Renders the start of a mount
-
Check whether the Container is valid
-
Call legacyRenderSubtreeIntoContainer (null, elemrnt, container, false, callback)
legacyRenderSubtreeIntoContainer
- ParentComponent = > null — — — — — — — — — — — — — — — SSR is special, the parent node
- Children => Element ———— Requires rendering of ReactElemtn
- container => container ———- HtmlElment
- ForceHydrate => false ————– SSR only, via Hydrate here will be true
- CallBack => callBack ———–
Initialize/update the Container based on whether root exists, create or obtain fiberRoot, and then start the update
Extract _reactRootContainer from container as a root of React
const root = container._reactRootContainer
Check if root exists, Update if so, initialize if not
If root exists:
Extract fiberRoot from root
const fiberRoot = root._internalRoot
Call updateContainer (children, fiberRoot parentComponent, callBack)
Note: Here callBack recurses to the first non-HTMLElement node on fiberRoot via getPublicRootInstance() and binds callBack to it. if (typeof callback === 'function') { const originalCallback = callback; callback = function() { const instance = getPublicRootInstance(fiberRoot); originalCallback.call(instance); }; }Copy the code
If root does not exist:
Call legacyCreateRootFromDOMContainer (contaiber forceHydrate) initializes the root. Assign root to container._reactrootContainer and extract _internalRoot from root as fiberRoot.
Call updateContainer (children, fiberRoot parentComponent, callBack).
// Note that when called here, it is non-batch. UnbatchedUpdates (() => {updateContainer(children, fiberRoot, parentComponent, callback); }); // updateContainer(). ^-^ is not discussed hereCopy the code
legacyCreateRootFromDOMContainer
- container ————— HTMLElement
- ForceHydrate — — — — — — — — — — — — ditto
Effect: Empty the Container and create root
- Determine if the Container needs to be emptied based on whether the forceHydrate and container have been marked as a ReactContainer (SSR does not need to be emptied, but web side initialization)
- Create a root node
shouleHydrate = forceHydrate && isReactContainer(contaiber)? { hydrate:true }:undefinde
Call createLegacyRoot (container, shouleHydrate)
createLegacyRoot
- container ————— HTMLElement
- Options: shouleHydrate – ignored
Introduce the static variable LegacyRoot = 0 as RootTag
Call new ReactDOMBlockingRoot (container, LegacyRoot, options)
ReactDOMBlockingRoot
- container ————— HTMLElement
- Tag — — — — — — — — — — — — — — — — — — — — – the root of the tag says to build the source of the root
- The options — — — — — — — — — — — — — — — — — to ignore
Create RootImpl and assign it to this._internalRoot (fiberRoot)
this._internalRoot = createRootImpl(container, tag, options);
// Render (children){root = this.\_internalRoot; UpdateContainer (children,root,null,null)} unmount(){const root = this._internalroot; const container = root.containerInfo; UpdateContainer (null, root, null, () => {// Remove fiber unmarkContainerAsRoot(container) from __reactContainer; }); }Copy the code
createRootImpl
- container ————— HTMLElement
- Tag — — — — — — — — — — — — — — — — — — — — – the root of the tag says to build the source of the root
- The options — — — — — — — — — — — — — — — — — to ignore
Function:
- Create root based on container
- Mark container as the current of root
- Add all listening events to the root container
Create root based on container
const root = createContainer(container, tag, hydrate, hydrationCallbacks);
Copy the code
Mark container as the current of root
// Add fiber markContainerAsRoot(root.current, container) for __reactContainer;Copy the code
Add all listening events to the root container
const rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; / / bind event listeners, special processing selectionchange listenToAllSupportedEvents (rootContainerElement);Copy the code
createContainer -> createFiberRoot
- containerInfo ————— HTMLElement
- Tag — — — — — — — — — — — — — — — — — — — — — — — — — the root tag said to build the source of the root
Function:
-
Create a root: FiberRoot
root = new FiberRootNode(containerInfo,tag)
-> root.containerInfo = containerInfo
-> root.tag = tag
-
Create RootFiber: Fiber
RootFiber = createHostRootFiber(tag);
Mode === NodeMode
HostRoot = 3; // indicates that the root node is created
Call createFiber (HostRoot, null, null, mode)
-> RootFiber.tag = HostRoot
-> RootFiber.mode = mode
-
Form a closed loop to point root.current to RootFiber and make root the first stateNode of Fiber
root.current = RootFiber
RootFiber.stateNode = root
-
Initialize the UpdateQueue of RootFiber
initializeUpdateQueue(RootFiber)
->queue.baseState = RootFiber.memoizedState
->RootFiber.updateQueus = queue
createFiber
- Tag ————————- fiber type
- PenddingProps ————— External data
- Key ————————- Unique identifier
- Mode ———————— is basically NodeMode
Effect: Generates a FiberNode
FiberNode.tag = tag FiberNode.penddingProps = penddingProps FiberNode.mode=mode FiberNode.key = key