跳到主要内容

React 内部类型

// Unwind Circular: moved from ReactFiberHooks.old
// 取消循环:从 ReactFiberHooks.old 移动
export type HookType =
| 'useState'
| 'useReducer'
| 'useContext'
| 'useRef'
| 'useEffect'
| 'useEffectEvent'
| 'useInsertionEffect'
| 'useLayoutEffect'
| 'useCallback'
| 'useMemo'
| 'useImperativeHandle'
| 'useDebugValue'
| 'useDeferredValue'
| 'useTransition'
| 'useSyncExternalStore'
| 'useId'
| 'useCacheRefresh'
| 'useOptimistic'
| 'useFormState'
| 'useActionState';

export type ContextDependency<T> = {
context: ReactContext<T>;
next: ContextDependency<mixed> | null;
memoizedValue: T;
// - ...
};

export type Dependencies = {
lanes: Lanes;
firstContext: ContextDependency<mixed> | null;
// 仅限开发
_debugThenableState?: null | ThenableState; // DEV-only
// - ...
};

export type MemoCache = {
data: Array<Array<any>>;
index: number;
};

// A Fiber is work on a Component that needs to be done or was done. There can
// be more than one per component.
// Fiber 是在组件上需要完成或已经完成的工作。每个组件可以有多个。
export type Fiber = {
// These first fields are conceptually members of an Instance. This used to
// be split into a separate type and intersected with the other Fiber fields,
// but until Flow fixes its intersection bugs, we've merged them into a
// single type.
//
// 这些最初的字段在概念上属于一个实例的成员。以前这部分会被拆分成一个单独的类型,并与其他
// Fiber 字段交叉,但在 Flow 修复其交叉类型的错误之前,我们将它们合并为一个类型。

// An Instance is shared between all versions of a component. We can easily
// break this out into a separate object to avoid copying so much to the
// alternate versions of the tree. We put this on a single object for now to
// minimize the number of objects created during the initial render.
//
// 一个实例在组件的所有版本之间共享。我们可以轻松地将其拆分到一个单独的对象中,以避免向树的
// 备用版本复制过多内容。我们暂时将其放在一个对象上,以尽量减少初始渲染期间创建的对象数量。

// Tag identifying the type of fiber.
// 标识 Fiber 类型的标签。
tag: WorkTag;

// Unique identifier of this child.
// 该子项的唯一标识符。
key: ReactKey;

// The value of element.type which is used to preserve the identity during
// reconciliation of this child.
//
// 元素类型 element.type 的值,用于在协调此子元素时保持其身份。
elementType: any;

// The resolved function/class/ associated with this fiber.
// 与此 fiber 关联的已解析函数/类。
type: any;

// The local state associated with this fiber.
// 与此 fiber 关联的本地状态。
stateNode: any;

// Conceptual aliases
// parent : Instance -> return The parent happens to be the same as the
// return fiber since we've merged the fiber and instance.
// 概念别名 parent : 实例 -> 返回父级恰好与返回纤维相同,因为我们已经合并了纤维和实例。

// Remaining fields belong to Fiber
// 剩余字段属于 Fiber

// The Fiber to return to after finishing processing this one.
// This is effectively the parent, but there can be multiple parents (two)
// so this is only the parent of the thing we're currently processing.
// It is conceptually the same as the return address of a stack frame.
//
// 处理完当前任务后要返回的 Fiber。这实际上是父 Fiber,但可能有多个父节点(两个),
// 所以它只是我们当前正在处理的任务的父节点。在概念上,它与栈帧的返回地址相同。
return: Fiber | null;

// Singly Linked List Tree Structure.
// 单向链表树结构。
child: Fiber | null;
sibling: Fiber | null;
index: number;

// The ref last used to attach this node.
// I'll avoid adding an owner field for prod and model that as functions.
// 上次使用的 ref 用于附加此节点。我将避免为 prod 添加 owner 字段,并将其建模为函数。
ref:
| null
// | (((handle: mixed) => void) & {_stringRef: ?string, ...})
| (((handle: mixed) => void) & { _stringRef: ?string })
| RefObject;

refCleanup: null | (() => void);

// Input is the data coming into process this fiber. Arguments. Props.
// 输入是进入该 fiber 的数据。参数。属性。
// This type will be more specific once we overload the tag.
// 一旦我们重载该标签,这种类型将会更具体。
pendingProps: any;
// 用于创建输出的属性。
memoizedProps: any; // The props used to create the output.

// A queue of state updates and callbacks.
// 一系列状态更新和回调。
updateQueue: mixed;

// The state used to create the output
// 用于创建输出的状态
memoizedState: any;

// Dependencies (contexts, events) for this fiber, if it has any
// 这个 fiber 的依赖项(上下文、事件),如果有的话
dependencies: Dependencies | null;

// Bitfield that describes properties about the fiber and its subtree. E.g.
// the ConcurrentMode flag indicates whether the subtree should be async-by-
// default. When a fiber is created, it inherits the mode of its
// parent. Additional flags can be set at creation time, but after that the
// value should remain unchanged throughout the fiber's lifetime, particularly
// before its child fibers are created.
//
// 描述 fiber 及其子树属性的位字段。例如: ConcurrentMode 标志指示子树是否默认应为异步。
// 当创建一个 fiber 时,它会继承其父节点的模式。可以在创建时设置额外的标志,但之后该值在整个
// fiber 的生命周期中应该保持不变,特别是在其子 fiber 创建之前。
mode: TypeOfMode;

// Effect
// 效果(副作用)
flags: Flags;
subtreeFlags: Flags;
deletions: Array<Fiber> | null;

lanes: Lanes;
childLanes: Lanes;

// This is a pooled version of a Fiber. Every fiber that gets updated will
// eventually have a pair. There are cases when we can clean up pairs to save
// memory if we need to.
//
// 这是一个 Fiber 的池化版本。每个被更新的 fiber 最终都会有一个配对。
// 在某些情况下,如果需要,我们可以清理配对以节省内存。
alternate: Fiber | null;

// Time spent rendering this Fiber and its descendants for the current update.
// This tells us how well the tree makes use of sCU for memoization.
// It is reset to 0 each time we render and only updated when we don't bailout.
// This field is only set when the enableProfilerTimer flag is enabled.
//
// 当前更新中渲染此 Fiber 及其子节点所花费的时间。这告诉我们树在使用 sCU 进行缓存时的效率。
// 每次渲染时都会重置为 0,并且仅在未中止的情况下更新。仅在启用 enableProfilerTimer 标志
// 时设置此字段。
actualDuration?: number;

// If the Fiber is currently active in the "render" phase,
// This marks the time at which the work began.
// This field is only set when the enableProfilerTimer flag is enabled.
//
// 如果这个 Fiber 当前处于“渲染”阶段, 这表示工作开始的时间。只有在启用 enableProfilerTimer
// 标志时才会设置此字段。
actualStartTime?: number;

// Duration of the most recent render time for this Fiber.
// This value is not updated when we bailout for memoization purposes.
// This field is only set when the enableProfilerTimer flag is enabled.
//
// 此 Fiber 最近一次渲染的持续时间。当因为记忆化而放弃渲染时,此值不会更新。
// 仅当启用 enableProfilerTimer 标志时,此字段才会被设置。
selfBaseDuration?: number;

// Sum of base times for all descendants of this Fiber.
// This value bubbles up during the "complete" phase.
// This field is only set when the enableProfilerTimer flag is enabled.
//
// 所有这个 Fiber 的子代的基础时间总和。该值在“完成”阶段会上升。仅当启用 enableProfilerTimer
// 标志时才设置此字段。
treeBaseDuration?: number;

// Conceptual aliases
// workInProgress : Fiber -> alternate The alternate used for reuse happens
// to be the same as work in progress.
// __DEV__ only
//
// 概念别名
// workInProgress : Fiber -> alternate 用于重用的 alternate 恰好与正在进行的工作相同。
// 仅在 __DEV__ 下

_debugInfo?: ReactDebugInfo | null;
_debugOwner?: ReactComponentInfo | Fiber | null;
_debugStack?: Error | null;
_debugTask?: ConsoleTask | null;
_debugNeedsRemount?: boolean;

// Used to verify that the order of hooks does not change between renders.
// 用于验证钩子的顺序在渲染之间是否不变。
_debugHookTypes?: Array<HookType> | null;
};

type BaseFiberRootProperties = {
// The type of root (legacy, batched, concurrent, etc.)
// 根节点类型(传统、批处理、并发等)
tag: RootTag;

// Any additional information from the host associated with this root.
// 与此根相关的主机的任何其他信息。
containerInfo: Container;
// Used only by persistent updates.
// 仅由持续更新使用。
pendingChildren: any;
// The currently active root fiber. This is the mutable root of the tree.
// 当前活动的根 fiber。这是树的可变根。
current: Fiber;

pingCache: WeakMap<Wakeable, Set<mixed>> | Map<Wakeable, Set<mixed>> | null;

// Timeout handle returned by setTimeout. Used to cancel a pending timeout, if
// it's superseded by a new one.
// setTimeout 返回的超时句柄。用于取消待处理的超时,如果它被新的超时取代。
timeoutHandle: TimeoutHandle | NoTimeout;
// When a root has a pending commit scheduled, calling this function will
// cancel it.
// 当根节点有待定的提交计划时,调用此函数将取消它。
// TODO: Can this be consolidated with timeoutHandle?
// 待办事项:能否与 timeoutHandle 合并?
cancelPendingCommit: null | (() => void);
// Top context object, used by renderSubtreeIntoContainer
// 顶层上下文对象,由 renderSubtreeIntoContainer 使用
context: Object | null;
pendingContext: Object | null;

// Used to create a linked list that represent all the roots that have
// pending work scheduled on them.
// 用于创建一个链表,表示所有有待处理工作计划的根节点。
next: FiberRoot | null;

// Node returned by Scheduler.scheduleCallback. Represents the next rendering
// task that the root will work on.
// 由 Scheduler.scheduleCallback 返回的节点。表示根节点将要处理的下一个渲染任务。
callbackNode: any;
callbackPriority: Lane;
expirationTimes: LaneMap<number>;
hiddenUpdates: LaneMap<Array<ConcurrentUpdate> | null>;

pendingLanes: Lanes;
suspendedLanes: Lanes;
pingedLanes: Lanes;
warmLanes: Lanes;
expiredLanes: Lanes;
// 仅启用默认过渡指示器
indicatorLanes: Lanes; // enableDefaultTransitionIndicator only
errorRecoveryDisabledLanes: Lanes;
shellSuspendCounter: number;

entangledLanes: Lanes;
entanglements: LaneMap<Lanes>;

pooledCache: Cache | null;
pooledCacheLanes: Lanes;

// TODO: In Fizz, id generation is specific to each server config. Maybe we
// should do this in Fiber, too? Deferring this decision for now because
// there's no other place to store the prefix except for an internal field on
// the public createRoot object, which the fiber tree does not currently have
// a reference to.
//
// 待办事项:在 Fizz 中,ID 生成是针对每个服务器配置特定的。也许我们在 Fiber 中也应该这样做?
// 暂时推迟这个决定,因为除了公共 createRoot 对象的内部字段外,没有其他地方可以存储前缀,而
// Fiber 树当前没有对此的引用。
identifierPrefix: string;

onUncaughtError: (
error: mixed,
// errorInfo: {+componentStack?: ?string},
errorInfo: { componentStack?: ?string },
) => void;
onCaughtError: (
error: mixed,
errorInfo: {
// +componentStack?: ?string,
componentStack?: ?string;
// +errorBoundary?: ?component(...props: any),
errorBoundary?: ?Component;
},
) => void;
onRecoverableError: (
error: mixed,
// errorInfo: {+componentStack?: ?string},
errorInfo: { componentStack?: ?string },
) => void;

// enableDefaultTransitionIndicator only
// 仅启用默认过渡指示器
onDefaultTransitionIndicator: () => void | (() => void);
pendingIndicator: null | (() => void);

formState: ReactFormState<any, any> | null;

// enableViewTransition only
// 仅启用视图过渡
// TODO: Make this a LaneMap.
// 待办:将其改为 LaneMap。
transitionTypes: null | TransitionTypes;
// enableGestureTransition only
// 仅启用手势过渡
pendingGestures: null | ScheduledGesture;
stoppingGestures: null | ScheduledGesture;
gestureClone: null | Instance;
};

// The following attributes are only used by DevTools and are only present in DEV builds.
// They enable DevTools Profiler UI to show which Fiber(s) scheduled a given commit.
//
// 以下属性仅供 DevTools 使用,并且仅在开发版本中存在。它们使 DevTools 性能分析器 UI 能显示是哪个 Fiber
// 调度了给定的提交。
type UpdaterTrackingOnlyFiberRootProperties = {
memoizedUpdaters: Set<Fiber>;
pendingUpdatersLaneMap: LaneMap<Set<Fiber>>;
};

export type SuspenseHydrationCallbacks = {
// +onHydrated?: (
onHydrated?: (hydrationBoundary: SuspenseInstance | ActivityInstance) => void;
// +onDeleted?: (hydrationBoundary: SuspenseInstance | ActivityInstance) => void,
onDeleted?: (hydrationBoundary: SuspenseInstance | ActivityInstance) => void;
// - ...
};

// The follow fields are only used by enableSuspenseCallback for hydration.
// 下面的字段仅由 enableSuspenseCallback 用于 hydration。
type SuspenseCallbackOnlyFiberRootProperties = {
hydrationCallbacks: null | SuspenseHydrationCallbacks;
};

export type TransitionTracingCallbacks = {
onTransitionStart?: (transitionName: string, startTime: number) => void;
onTransitionProgress?: (
transitionName: string,
startTime: number,
currentTime: number,
pending: Array<{ name: null | string }>,
) => void;
onTransitionIncomplete?: (
transitionName: string,
startTime: number,
deletions: Array<{
type: string;
name?: string | null;
endTime: number;
}>,
) => void;
onTransitionComplete?: (
transitionName: string,
startTime: number,
endTime: number,
) => void;
onMarkerProgress?: (
transitionName: string,
marker: string,
startTime: number,
currentTime: number,
pending: Array<{ name: null | string }>,
) => void;
onMarkerIncomplete?: (
transitionName: string,
marker: string,
startTime: number,
deletions: Array<{
type: string;
name?: string | null;
endTime: number;
}>,
) => void;
onMarkerComplete?: (
transitionName: string,
marker: string,
startTime: number,
endTime: number,
) => void;
};

// The following fields are only used in transition tracing in Profile builds
// 以下字段仅在配置文件构建中的过渡跟踪中使用
type TransitionTracingOnlyFiberRootProperties = {
transitionCallbacks: null | TransitionTracingCallbacks;
transitionLanes: LaneMap<Set<Transition> | null>;
// Transitions on the root can be represented as a bunch of tracing markers.
// Each entangled group of transitions can be treated as a tracing marker.
// It will have a set of pending suspense boundaries. These transitions
// are considered complete when the pending suspense boundaries set is
// empty. We can represent this as a Map of transitions to suspense
// boundary sets
//
// 根节点上的过渡可以表示为一堆追踪标记。每个纠缠的过渡组可以被视为一个追踪标记。
// 它将有一组待处理的 suspense 边界。当待处理的 suspense 边界集合为空时,这些过渡
// 被认为已完成。我们可以将其表示为从过渡到 suspense 边界集合的 Map
incompleteTransitions: Map<Transition, TracingMarkerInstance>;
};

type ProfilerCommitHooksOnlyFiberRootProperties = {
effectDuration: number;
passiveEffectDuration: number;
};

// Exported FiberRoot type includes all properties,
// To avoid requiring potentially error-prone :any casts throughout the project.
// The types are defined separately within this file to ensure they stay in sync.
//
// 导出的 FiberRoot 类型包含所有属性,以避免在整个项目中频繁使用可能出错的 :any 类型转换。
// 类型在此文件中单独定义,以确保它们保持同步。
export type FiberRoot =
// {

// ...BaseFiberRootProperties,
// ...SuspenseCallbackOnlyFiberRootProperties,
// ...UpdaterTrackingOnlyFiberRootProperties,
// ...TransitionTracingOnlyFiberRootProperties,
// ...ProfilerCommitHooksOnlyFiberRootProperties,
// };
BaseFiberRootProperties &
SuspenseCallbackOnlyFiberRootProperties &
UpdaterTrackingOnlyFiberRootProperties &
TransitionTracingOnlyFiberRootProperties &
ProfilerCommitHooksOnlyFiberRootProperties;

type BasicStateAction<S> = ((S) => S) | S;
type Dispatch<A> = (A) => void;

export type Dispatcher = {
// use: <T>(Usable<T>) => T,
use: <T>(usable: Usable<T>) => T;
readContext<T>(context: ReactContext<T>): T;
useState<S>(initialState: (() => S) | S): [S, Dispatch<BasicStateAction<S>>];
useReducer<S, I, A>(
reducer: (S, A) => S,
initialArg: I,
init?: (I) => S,
): [S, Dispatch<A>];
useContext<T>(context: ReactContext<T>): T;
useRef<T>(initialValue: T): { current: T };
useEffect(
create: () => (() => void) | void,
deps: Array<mixed> | void | null,
): void;
// TODO: Non-nullable once `enableUseEffectEventHook` is on everywhere.
// 待办:一旦 `enableUseEffectEventHook` 在所有地方启用,即可非空。
// useEffectEvent?: <Args, F: (...Array<Args>) => mixed>(callback: F) => F,
useEffectEvent?: <Args, F>(callback: F) => F;
useInsertionEffect(
create: () => (() => void) | void,
deps: Array<mixed> | void | null,
): void;
useLayoutEffect(
create: () => (() => void) | void,
deps: Array<mixed> | void | null,
): void;
useCallback<T>(callback: T, deps: Array<mixed> | void | null): T;
useMemo<T>(nextCreate: () => T, deps: Array<mixed> | void | null): T;
useImperativeHandle<T>(
ref: { current: T | null } | ((inst: T | null) => mixed) | null | void,
create: () => T,
deps: Array<mixed> | void | null,
): void;
useDebugValue<T>(value: T, formatterFn: ?((value: T) => mixed)): void;
useDeferredValue<T>(value: T, initialValue?: T): T;
useTransition(): [
boolean,
(callback: () => void, options?: StartTransitionOptions) => void,
];
useSyncExternalStore<T>(
subscribe: (parm: () => void) => () => void,
getSnapshot: () => T,
getServerSnapshot?: () => T,
): T;
useId(): string;
useCacheRefresh: () => <T>(a?: ?(() => T), b: ?T) => void;
useMemoCache: (size: number) => Array<any>;
useHostTransitionStatus: () => TransitionStatus;
useOptimistic: <S, A>(
passthrough: S,
reducer: ?((S, A) => S),
) => [S, (A) => void];
useFormState: <S, P>(
action: (a: Awaited<S>, P) => S,
initialState: Awaited<S>,
permalink?: string,
) => [Awaited<S>, (P) => void, boolean];
useActionState: <S, P>(
action: (a: Awaited<S>, P) => S,
initialState: Awaited<S>,
permalink?: string,
) => [Awaited<S>, (p: P) => void, boolean];
};

export type AsyncDispatcher = {
getCacheForType: <T>(resourceType: () => T) => T;
cacheSignal: () => null | AbortSignal;
// DEV-only
// 仅供开发使用
getOwner: () => null | Fiber | ReactComponentInfo | ComponentStackNode;
};