结构示意图
function legacyRenderSubtreeIntoContainer(parentComponent, // nullchildren, //同上container, // <div id="root"></div>forceHydrate, // falsecallback // undefined) {let root = container._reactRootContainerroot = container._reactRootContainer = legacyCreateRootFromDOMContainer(container,forceHydrate)}
function legacyCreateRootFromDOMContainer(container, forceHydrate) {const shouldHydrate =forceHydrate || shouldHydrateDueToLegacyHeuristic(container)if (!shouldHydrate) {let warned = falselet rootSiblingwhile ((rootSibling = container.lastChild)) {container.removeChild(rootSibling)}}const isConcurrent = falsereturn new ReactRoot(container, isConcurrent, shouldHydrate)}
function ReactRoot(container, isConcurrent, hydrate) {const root = DOMRenderer.createContainer(container, isConcurrent, hydrate)this._internalRoot = root}
export function createContainer(containerInfo, isConcurrent, hydrate) {return createFiberRoot(containerInfo, isConcurrent, hydrate)}
FiberRoot.current = RootFiberRootFiber.stateNode = FiberRoot
export function createFiberRoot(containerInfo, isConcurrent, hydrate) {const uninitializedFiber = createHostRootFiber(isConcurrent)let rootif (enableSchedulerTracing) {root = {current: uninitializedFiber,containerInfo: containerInfo,pendingChildren: null,earliestPendingTime: NoWork,latestPendingTime: NoWork,earliestSuspendedTime: NoWork,latestSuspendedTime: NoWork,latestPingedTime: NoWork,didError: false,pendingCommitExpirationTime: NoWork,finishedWork: null,timeoutHandle: noTimeout,context: null,pendingContext: null,hydrate,nextExpirationTimeToWorkOn: NoWork,expirationTime: NoWork,firstBatch: null,nextScheduledRoot: null,interactionThreadID: unstable_getThreadID(),memoizedInteractions: new Set(),pendingInteractionMap: new Map(),}} else {root = {current: uninitializedFiber,containerInfo: containerInfo,pendingChildren: null,earliestPendingTime: NoWork,latestPendingTime: NoWork,earliestSuspendedTime: NoWork,latestSuspendedTime: NoWork,latestPingedTime: NoWork,didError: false,pendingCommitExpirationTime: NoWork,finishedWork: null,timeoutHandle: noTimeout,context: null,pendingContext: null,hydrate,nextExpirationTimeToWorkOn: NoWork,expirationTime: NoWork,firstBatch: null,nextScheduledRoot: null,}}uninitializedFiber.stateNode = rootreturn root}
export function createHostRootFiber(isConcurrent) {let mode = isConcurrent ? ConcurrentMode | StrictMode : NoContextif (enableProfilerTimer && isDevToolsPresent) {mode |= ProfileMode}return createFiber(HostRoot, null, null, mode)}
const createFiber = function (tag, pendingProps, key, mode) {return new FiberNode(tag, pendingProps, key, mode)}
function FiberNode(tag, pendingProps, key, mode) {this.tag = tagthis.key = keythis.elementType = nullthis.type = nullthis.stateNode = nullthis.return = nullthis.child = nullthis.sibling = nullthis.index = 0this.ref = nullthis.pendingProps = pendingPropsthis.memoizedProps = nullthis.updateQueue = nullthis.memoizedState = nullthis.firstContextDependency = nullthis.mode = modethis.effectTag = NoEffectthis.nextEffect = nullthis.firstEffect = nullthis.lastEffect = nullthis.expirationTime = NoWorkthis.childExpirationTime = NoWorkthis.alternate = nullif (enableProfilerTimer) {this.actualDuration = 0this.actualStartTime = -1this.selfBaseDuration = 0this.treeBaseDuration = 0}}
export type Fiber = {tag: WorkTag,key: null | string,elementType: any,type: any,stateNode: any,return: Fiber | null,child: Fiber | null,sibling: Fiber | null,index: number,ref: null | (((handle: mixed) => void) & {_stringRef: ?string}) | RefObject,pendingProps: any,memoizedProps: any,updateQueue: UpdateQueue<any> | null,memoizedState: any,firstContextDependency: ContextDependency<mixed> | null,mode: TypeOfMode,effectTag: SideEffectTag,nextEffect: Fiber | null,firstEffect: Fiber | null,lastEffect: Fiber | null,expirationTime: ExpirationTime,childExpirationTime: ExpirationTime,alternate: Fiber | null,actualDuration?: number,actualStartTime?: number,selfBaseDuration?: number,treeBaseDuration?: number,_debugID?: number,_debugSource?: Source | null,_debugOwner?: Fiber | null,_debugIsCurrentlyTiming?: boolean,|};
至此介绍了 fiber 根节点生成的整个过程