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