/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-reconciler/src/ReactFiberRoot.js
237 строк
7 KB
Jan Kassens
Update Flow to 0.263 (#34269)
22 авг 2025, 19:10
Не верифицирован
22 авг 2025, 19:10
6de32a5
Код
Авторство
О чём код?
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes'; import type { FiberRoot, SuspenseHydrationCallbacks, TransitionTracingCallbacks, } from './ReactInternalTypes'; import type {RootTag} from './ReactRootTags'; import type {Cache} from './ReactFiberCacheComponent'; import type {Container} from './ReactFiberConfig'; import {noTimeout} from './ReactFiberConfig'; import {createHostRootFiber} from './ReactFiber'; import { NoLane, NoLanes, NoTimestamp, TotalLanes, createLaneMap, } from './ReactFiberLane'; import { enableSuspenseCallback, enableProfilerCommitHooks, enableProfilerTimer, enableUpdaterTracking, enableTransitionTracing, disableLegacyMode, enableViewTransition, enableGestureTransition, enableDefaultTransitionIndicator, } from 'shared/ReactFeatureFlags'; import {initializeUpdateQueue} from './ReactFiberClassUpdateQueue'; import {LegacyRoot, ConcurrentRoot} from './ReactRootTags'; import {createCache, retainCache} from './ReactFiberCacheComponent'; export type RootState = { element: any, isDehydrated: boolean, cache: Cache, }; function FiberRootNode( this: $FlowFixMe, containerInfo: any, // $FlowFixMe[missing-local-annot] tag, hydrate: any, identifierPrefix: any, onUncaughtError: any, onCaughtError: any, onRecoverableError: any, onDefaultTransitionIndicator: any, formState: ReactFormState<any, any> | null, ) { this.tag = disableLegacyMode ? ConcurrentRoot : tag; this.containerInfo = containerInfo; this.pendingChildren = null; this.current = null; this.pingCache = null; this.timeoutHandle = noTimeout; this.cancelPendingCommit = null; this.context = null; this.pendingContext = null; this.next = null; this.callbackNode = null; this.callbackPriority = NoLane; this.expirationTimes = createLaneMap(NoTimestamp); this.pendingLanes = NoLanes; this.suspendedLanes = NoLanes; this.pingedLanes = NoLanes; this.warmLanes = NoLanes; this.expiredLanes = NoLanes; if (enableDefaultTransitionIndicator) { this.indicatorLanes = NoLanes; } this.errorRecoveryDisabledLanes = NoLanes; this.shellSuspendCounter = 0; this.entangledLanes = NoLanes; this.entanglements = createLaneMap(NoLanes); this.hiddenUpdates = createLaneMap(null); this.identifierPrefix = identifierPrefix; this.onUncaughtError = onUncaughtError; this.onCaughtError = onCaughtError; this.onRecoverableError = onRecoverableError; if (enableDefaultTransitionIndicator) { this.onDefaultTransitionIndicator = onDefaultTransitionIndicator; this.pendingIndicator = null; } this.pooledCache = null; this.pooledCacheLanes = NoLanes; if (enableSuspenseCallback) { this.hydrationCallbacks = null; } this.formState = formState; if (enableViewTransition) { this.transitionTypes = null; } if (enableGestureTransition) { this.pendingGestures = null; this.stoppingGestures = null; this.gestureClone = null; } this.incompleteTransitions = new Map(); if (enableTransitionTracing) { this.transitionCallbacks = null; this.transitionLanes = createLaneMap(null); } if (enableProfilerTimer && enableProfilerCommitHooks) { this.effectDuration = -0; this.passiveEffectDuration = -0; } if (enableUpdaterTracking) { this.memoizedUpdaters = new Set(); const pendingUpdatersLaneMap = (this.pendingUpdatersLaneMap = []); for (let i = 0; i < TotalLanes; i++) { pendingUpdatersLaneMap.push(new Set()); } } if (__DEV__) { if (disableLegacyMode) { // TODO: This varies by each renderer. this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()'; } else { switch (tag) { case ConcurrentRoot: this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()'; break; case LegacyRoot: this._debugRootType = hydrate ? 'hydrate()' : 'render()'; break; } } } } export function createFiberRoot( containerInfo: Container, tag: RootTag, hydrate: boolean, initialChildren: ReactNodeList, hydrationCallbacks: null | SuspenseHydrationCallbacks, isStrictMode: boolean, // TODO: We have several of these arguments that are conceptually part of the // host config, but because they are passed in at runtime, we have to thread // them through the root constructor. Perhaps we should put them all into a // single type, like a DynamicHostConfig that is defined by the renderer. identifierPrefix: string, formState: ReactFormState<any, any> | null, onUncaughtError: ( error: mixed, errorInfo: {+componentStack?: ?string}, ) => void, onCaughtError: ( error: mixed, errorInfo: { +componentStack?: ?string, +errorBoundary?: ?component(...props: any), }, ) => void, onRecoverableError: ( error: mixed, errorInfo: {+componentStack?: ?string}, ) => void, onDefaultTransitionIndicator: () => void | (() => void), transitionCallbacks: null | TransitionTracingCallbacks, ): FiberRoot { // $FlowFixMe[invalid-constructor] Flow no longer supports calling new on functions const root: FiberRoot = (new FiberRootNode( containerInfo, tag, hydrate, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, onDefaultTransitionIndicator, formState, ): any); if (enableSuspenseCallback) { root.hydrationCallbacks = hydrationCallbacks; } if (enableTransitionTracing) { root.transitionCallbacks = transitionCallbacks; } // Cyclic construction. This cheats the type system right now because // stateNode is any. const uninitializedFiber = createHostRootFiber(tag, isStrictMode); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; const initialCache = createCache(); retainCache(initialCache); // The pooledCache is a fresh cache instance that is used temporarily // for newly mounted boundaries during a render. In general, the // pooledCache is always cleared from the root at the end of a render: // it is either released when render commits, or moved to an Offscreen // component if rendering suspends. Because the lifetime of the pooled // cache is distinct from the main memoizedState.cache, it must be // retained separately. root.pooledCache = initialCache; retainCache(initialCache); const initialState: RootState = { element: initialChildren, isDehydrated: hydrate, cache: initialCache, }; uninitializedFiber.memoizedState = initialState; initializeUpdateQueue(uninitializedFiber); return root; }