react/packages/shared/ReactTypes.js

220 lines
5.7 KiB
JavaScript
Raw Normal View History

2016-05-27 09:13:21 +08:00
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
2016-05-27 09:13:21 +08:00
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
2016-05-27 09:13:21 +08:00
*
* @flow
*/
2022-09-13 01:44:58 +08:00
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
2017-03-14 08:05:18 +08:00
export type ReactNode =
| React$Element<any>
2017-03-14 08:05:18 +08:00
| ReactPortal
| ReactText
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
| ReactFragment
| ReactProvider<any>
| ReactConsumer<any>;
export type ReactEmpty = null | void | boolean;
2016-05-27 09:13:21 +08:00
export type ReactFragment = ReactEmpty | Iterable<React$Node>;
2016-05-27 09:13:21 +08:00
export type ReactNodeList = ReactEmpty | React$Node;
2016-05-27 09:13:21 +08:00
export type ReactText = string | number;
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
export type ReactProvider<T> = {
$$typeof: symbol | number,
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
type: ReactProviderType<T>,
key: null | string,
ref: null,
props: {
value: T,
children?: ReactNodeList,
...
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
},
...
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
};
export type ReactProviderType<T> = {
$$typeof: symbol | number,
_context: ReactContext<T>,
...
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
};
export type ReactConsumer<T> = {
$$typeof: symbol | number,
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
type: ReactContext<T>,
key: null | string,
ref: null,
props: {
children: (value: T) => ReactNodeList,
...
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
},
...
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
};
export type ReactContext<T> = {
$$typeof: symbol | number,
Consumer: ReactContext<T>,
Provider: ReactProviderType<T>,
_currentValue: T,
_currentValue2: T,
Use unique thread ID for each partial render to access Context (#14182) * BUG: ReactPartialRenderer / New Context polutes mutable global state The new context API stores the provided values on the shared context instance. When used in a synchronous context, this is not an issue. However when used in an concurrent context this can cause a "push provider" from one react render to have an effect on an unrelated concurrent react render. I've encountered this bug in production when using renderToNodeStream, which asks ReactPartialRenderer for bytes up to a high water mark before yielding. If two Node Streams are created and read from in parallel, the state of one can polute the other. I wrote a failing test to illustrate the conditions under which this happens. I'm also concerned that the experimental concurrent/async React rendering on the client could suffer from the same issue. * Use unique thread ID for each partial render to access Context This first adds an allocator that keeps track of a unique ThreadID index for each currently executing partial renderer. IDs are not just growing but are reused as streams are destroyed. This ensures that IDs are kept nice and compact. This lets us use an "array" for each Context object to store the current values. The look up for these are fast because they're just looking up an offset in a tightly packed "array". I don't use an actual Array object to store the values. Instead, I rely on that VMs (notably V8) treat storage of numeric index property access as a separate "elements" allocation. This lets us avoid an extra indirection. However, we must ensure that these arrays are not holey to preserve this feature. To do that I store the _threadCount on each context (effectively it takes the place of the .length property on an array). This lets us first validate that the context has enough slots before we access the slot. If not, we fill in the slots with the default value.
2018-11-10 07:38:20 +08:00
_threadCount: number,
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
// DEV only
_currentRenderer?: Object | null,
_currentRenderer2?: Object | null,
// This value may be added by application code
// to improve DEV tooling display names
displayName?: string,
[ServerContext] Flight support for ServerContext (#23244) * Flight side of server context * 1 more test * rm unused function * flow+prettier * flow again =) * duplicate ReactServerContext across packages * store default value when lazily initializing server context * . * better comment * derp... missing import * rm optional chaining * missed feature flag * React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? * add warning if non ServerContext passed into useServerContext * pass context in as array of arrays * make importServerContext nott pollute the global context state * merge main * remove useServerContext * dont rely on object getters in ReactServerContext and disallow JSX * add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry * gate test case as experimental * feedback * remove unions * Lint * fix oopsies (tests/lint/mismatching arguments/signatures * lint again * replace-fork * remove extraneous change * rebase * 1 more test * rm unused function * flow+prettier * flow again =) * duplicate ReactServerContext across packages * store default value when lazily initializing server context * . * better comment * derp... missing import * rm optional chaining * missed feature flag * React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? * add warning if non ServerContext passed into useServerContext * pass context in as array of arrays * make importServerContext nott pollute the global context state * merge main * remove useServerContext * dont rely on object getters in ReactServerContext and disallow JSX * add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry * gate test case as experimental * feedback * remove unions * Lint * fix oopsies (tests/lint/mismatching arguments/signatures * lint again * replace-fork * remove extraneous change * rebase * reinline * rebase * add back changes lost due to rebase being hard * emit chunk for provider * remove case for React provider type * update type for SomeChunk * enable flag with experimental * add missing types * fix flow type * missing type * t: any * revert extraneous type change * better type * better type * feedback * change import to type import * test? * test? * remove react-dom * remove react-native-renderer from react-server-native-relay/package.json * gate change in FiberNewContext, getComponentNameFromType, use switch statement in FlightServer * getComponentNameFromTpe: server context type gated and use displayName if available * fallthrough * lint.... * POP * lint
2022-03-08 20:55:32 +08:00
// only used by ServerContext
_defaultValue: T,
_globalName: string,
...
New context API (#11818) * New context API Introduces a declarative context API that propagates updates even when shouldComponentUpdate returns false. * Fuzz tester for context * Use ReactElement for provider and consumer children * Unify more branches in createFiberFromElement * Compare context values using Object.is Same semantics as PureComponent/shallowEqual. * Add support for Provider and Consumer to server-side renderer * Store providers on global stack Rather than using a linked list stored on the context type. The global stack can be reset in case of an interruption or error, whereas with the linked list implementation, you'd need to keep track of every context type. * Put new context API behind a feature flag We'll enable this in www only for now. * Store nearest provider on context object * Handle reentrancy in server renderer Context stack should be per server renderer instance. * Bailout of consumer updates using bitmask The context type defines an optional function that compares two context values, returning a bitfield. A consumer may specify the bits it needs for rendering. If a provider's context changes, and the consumer's bits do not intersect with the changed bits, we can skip the consumer. This is similar to how selectors are used in Redux but fast enough to do while scanning the tree. The only user code involved is the function that computes the changed bits. But that's only called once per provider update, not for every consumer. * Store current value and changed bits on context object There are fewer providers than consumers, so better to do this work at the provider. * Use maximum of 31 bits for bitmask This is the largest integer size in V8 on 32-bit systems. Warn in development if too large a number is used. * ProviderComponent -> ContextProvider, ConsumerComponent -> ContextConsumer * Inline Object.is * Warn if multiple renderers concurrently render the same context provider Let's see if we can get away with not supporting this for now. If it turns out that it's needed, we can fall back to backtracking the fiber return path. * Nits that came up during review
2018-01-25 11:36:22 +08:00
};
[ServerContext] Flight support for ServerContext (#23244) * Flight side of server context * 1 more test * rm unused function * flow+prettier * flow again =) * duplicate ReactServerContext across packages * store default value when lazily initializing server context * . * better comment * derp... missing import * rm optional chaining * missed feature flag * React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? * add warning if non ServerContext passed into useServerContext * pass context in as array of arrays * make importServerContext nott pollute the global context state * merge main * remove useServerContext * dont rely on object getters in ReactServerContext and disallow JSX * add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry * gate test case as experimental * feedback * remove unions * Lint * fix oopsies (tests/lint/mismatching arguments/signatures * lint again * replace-fork * remove extraneous change * rebase * 1 more test * rm unused function * flow+prettier * flow again =) * duplicate ReactServerContext across packages * store default value when lazily initializing server context * . * better comment * derp... missing import * rm optional chaining * missed feature flag * React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? * add warning if non ServerContext passed into useServerContext * pass context in as array of arrays * make importServerContext nott pollute the global context state * merge main * remove useServerContext * dont rely on object getters in ReactServerContext and disallow JSX * add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry * gate test case as experimental * feedback * remove unions * Lint * fix oopsies (tests/lint/mismatching arguments/signatures * lint again * replace-fork * remove extraneous change * rebase * reinline * rebase * add back changes lost due to rebase being hard * emit chunk for provider * remove case for React provider type * update type for SomeChunk * enable flag with experimental * add missing types * fix flow type * missing type * t: any * revert extraneous type change * better type * better type * feedback * change import to type import * test? * test? * remove react-dom * remove react-native-renderer from react-server-native-relay/package.json * gate change in FiberNewContext, getComponentNameFromType, use switch statement in FlightServer * getComponentNameFromTpe: server context type gated and use displayName if available * fallthrough * lint.... * POP * lint
2022-03-08 20:55:32 +08:00
export type ServerContextJSONValue =
| string
| boolean
| number
| null
| $ReadOnlyArray<ServerContextJSONValue>
| {+[key: string]: ServerContextJSONValue};
[ServerContext] Flight support for ServerContext (#23244) * Flight side of server context * 1 more test * rm unused function * flow+prettier * flow again =) * duplicate ReactServerContext across packages * store default value when lazily initializing server context * . * better comment * derp... missing import * rm optional chaining * missed feature flag * React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? * add warning if non ServerContext passed into useServerContext * pass context in as array of arrays * make importServerContext nott pollute the global context state * merge main * remove useServerContext * dont rely on object getters in ReactServerContext and disallow JSX * add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry * gate test case as experimental * feedback * remove unions * Lint * fix oopsies (tests/lint/mismatching arguments/signatures * lint again * replace-fork * remove extraneous change * rebase * 1 more test * rm unused function * flow+prettier * flow again =) * duplicate ReactServerContext across packages * store default value when lazily initializing server context * . * better comment * derp... missing import * rm optional chaining * missed feature flag * React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? * add warning if non ServerContext passed into useServerContext * pass context in as array of arrays * make importServerContext nott pollute the global context state * merge main * remove useServerContext * dont rely on object getters in ReactServerContext and disallow JSX * add symbols to devtools + rename globalServerContextRegistry to just ContextRegistry * gate test case as experimental * feedback * remove unions * Lint * fix oopsies (tests/lint/mismatching arguments/signatures * lint again * replace-fork * remove extraneous change * rebase * reinline * rebase * add back changes lost due to rebase being hard * emit chunk for provider * remove case for React provider type * update type for SomeChunk * enable flag with experimental * add missing types * fix flow type * missing type * t: any * revert extraneous type change * better type * better type * feedback * change import to type import * test? * test? * remove react-dom * remove react-native-renderer from react-server-native-relay/package.json * gate change in FiberNewContext, getComponentNameFromType, use switch statement in FlightServer * getComponentNameFromTpe: server context type gated and use displayName if available * fallthrough * lint.... * POP * lint
2022-03-08 20:55:32 +08:00
export type ReactServerContext<T: any> = ReactContext<T>;
ReactNative flat renderer bundles (#9626) * Split ReactNativeFiber into separate ReactNativeFiberRenderer module Hopefully this is sufficient to work around Rollup circular dependency problems. (To be seen in subsequent commits...) * Split findNodeHandle into findNodeHandleFiber + findNodeHandleStack This allowed me to remove the ReactNative -> findNodeHandle injections, which should in turn allow me to require a fully-functional findNodeHandle without going through ReactNative. This will hopefully allow ReactNativeBaseomponent to avoid a circular dependency. * Un-forked findNodeHandle in favor of just inlining the findNode function impl * takeSnapshot no longer requires/depends-on ReactNative for findNodeHandle Instead it uses the new, renderer-specific wrappers (eg findNodeHandleFiberWrapper and findNodeHandleStackWrapper) to ensure the returned value is numeric (or null). This avoids a circular dependency that would trip up Rollup. * NativeMethodsMixin requires findNodeHandler wrapper(s) directly rather than ReactNative This works around a potential circular dependency that would break the Rollup build * Add RN_* build targets to hash-finle-name check * Strip @providesModule annotations from headers for RN_* builds * Added process.env.REACT_NATIVE_USE_FIBER to ReactNativeFeatureFlags This is kind of a hacky solution, but it is temporary. It works around the fact that ReactNativeFeatureFlag values need to be set at build time in order to avoid a mismatch between runtime flag values. DOM avoids the need to do this by using injection but Native is not able to use this same approach due to circular dependency issues. * Moved a couple of SECRET exports to dev-only. Removed SyntheticEvent and PooledClass from SECRET exports. Converted Rollup helper function to use named params. * Split NativeMethodsMixins interface and object-type * Add @noflow header to flat-bundle template to avoid triggering Flow problems When Flow tries to infer such a large file, it consumes massive amounts of CPU/RAM and can often lead to programs crashing. It is better for such large files to use .flow.js types instead. * NativeMethodsMixin and ReactNativeFiberHostComponent now share the same Flow type * Collocated (externally exposed) ReactTypes and ReactNativeTypes into single files to be synced to fbsource. ReactNativeFiber and ReactNativeStack use ReactNativeType Flow type * Build script syncs RN types and PooledClass automatically * Added optional sync-RN step to Rollup build script * Added results.json for new RN bundles
2017-05-25 00:06:30 +08:00
export type ReactPortal = {
$$typeof: symbol | number,
ReactNative flat renderer bundles (#9626) * Split ReactNativeFiber into separate ReactNativeFiberRenderer module Hopefully this is sufficient to work around Rollup circular dependency problems. (To be seen in subsequent commits...) * Split findNodeHandle into findNodeHandleFiber + findNodeHandleStack This allowed me to remove the ReactNative -> findNodeHandle injections, which should in turn allow me to require a fully-functional findNodeHandle without going through ReactNative. This will hopefully allow ReactNativeBaseomponent to avoid a circular dependency. * Un-forked findNodeHandle in favor of just inlining the findNode function impl * takeSnapshot no longer requires/depends-on ReactNative for findNodeHandle Instead it uses the new, renderer-specific wrappers (eg findNodeHandleFiberWrapper and findNodeHandleStackWrapper) to ensure the returned value is numeric (or null). This avoids a circular dependency that would trip up Rollup. * NativeMethodsMixin requires findNodeHandler wrapper(s) directly rather than ReactNative This works around a potential circular dependency that would break the Rollup build * Add RN_* build targets to hash-finle-name check * Strip @providesModule annotations from headers for RN_* builds * Added process.env.REACT_NATIVE_USE_FIBER to ReactNativeFeatureFlags This is kind of a hacky solution, but it is temporary. It works around the fact that ReactNativeFeatureFlag values need to be set at build time in order to avoid a mismatch between runtime flag values. DOM avoids the need to do this by using injection but Native is not able to use this same approach due to circular dependency issues. * Moved a couple of SECRET exports to dev-only. Removed SyntheticEvent and PooledClass from SECRET exports. Converted Rollup helper function to use named params. * Split NativeMethodsMixins interface and object-type * Add @noflow header to flat-bundle template to avoid triggering Flow problems When Flow tries to infer such a large file, it consumes massive amounts of CPU/RAM and can often lead to programs crashing. It is better for such large files to use .flow.js types instead. * NativeMethodsMixin and ReactNativeFiberHostComponent now share the same Flow type * Collocated (externally exposed) ReactTypes and ReactNativeTypes into single files to be synced to fbsource. ReactNativeFiber and ReactNativeStack use ReactNativeType Flow type * Build script syncs RN types and PooledClass automatically * Added optional sync-RN step to Rollup build script * Added results.json for new RN bundles
2017-05-25 00:06:30 +08:00
key: null | string,
containerInfo: any,
children: ReactNodeList,
// TODO: figure out the API for cross-renderer implementation.
implementation: any,
...
ReactNative flat renderer bundles (#9626) * Split ReactNativeFiber into separate ReactNativeFiberRenderer module Hopefully this is sufficient to work around Rollup circular dependency problems. (To be seen in subsequent commits...) * Split findNodeHandle into findNodeHandleFiber + findNodeHandleStack This allowed me to remove the ReactNative -> findNodeHandle injections, which should in turn allow me to require a fully-functional findNodeHandle without going through ReactNative. This will hopefully allow ReactNativeBaseomponent to avoid a circular dependency. * Un-forked findNodeHandle in favor of just inlining the findNode function impl * takeSnapshot no longer requires/depends-on ReactNative for findNodeHandle Instead it uses the new, renderer-specific wrappers (eg findNodeHandleFiberWrapper and findNodeHandleStackWrapper) to ensure the returned value is numeric (or null). This avoids a circular dependency that would trip up Rollup. * NativeMethodsMixin requires findNodeHandler wrapper(s) directly rather than ReactNative This works around a potential circular dependency that would break the Rollup build * Add RN_* build targets to hash-finle-name check * Strip @providesModule annotations from headers for RN_* builds * Added process.env.REACT_NATIVE_USE_FIBER to ReactNativeFeatureFlags This is kind of a hacky solution, but it is temporary. It works around the fact that ReactNativeFeatureFlag values need to be set at build time in order to avoid a mismatch between runtime flag values. DOM avoids the need to do this by using injection but Native is not able to use this same approach due to circular dependency issues. * Moved a couple of SECRET exports to dev-only. Removed SyntheticEvent and PooledClass from SECRET exports. Converted Rollup helper function to use named params. * Split NativeMethodsMixins interface and object-type * Add @noflow header to flat-bundle template to avoid triggering Flow problems When Flow tries to infer such a large file, it consumes massive amounts of CPU/RAM and can often lead to programs crashing. It is better for such large files to use .flow.js types instead. * NativeMethodsMixin and ReactNativeFiberHostComponent now share the same Flow type * Collocated (externally exposed) ReactTypes and ReactNativeTypes into single files to be synced to fbsource. ReactNativeFiber and ReactNativeStack use ReactNativeType Flow type * Build script syncs RN types and PooledClass automatically * Added optional sync-RN step to Rollup build script * Added results.json for new RN bundles
2017-05-25 00:06:30 +08:00
};
export type RefObject = {
current: any,
};
export type ReactScope = {
$$typeof: symbol | number,
};
export type ReactScopeQuery = (
type: string,
props: {[string]: mixed, ...},
instance: mixed,
) => boolean;
export type ReactScopeInstance = {
DO_NOT_USE_queryAllNodes(ReactScopeQuery): null | Array<Object>,
DO_NOT_USE_queryFirstNode(ReactScopeQuery): null | Object,
containsNode(Object): boolean,
getChildContextValues: <T>(context: ReactContext<T>) => Array<T>,
};
// Mutable source version can be anything (e.g. number, string, immutable data structure)
// so long as it changes every time any part of the source changes.
export type MutableSourceVersion = $NonMaybeType<mixed>;
export type MutableSourceGetSnapshotFn<
Source: $NonMaybeType<mixed>,
Snapshot,
> = (source: Source) => Snapshot;
export type MutableSourceSubscribeFn<Source: $NonMaybeType<mixed>, Snapshot> = (
source: Source,
callback: (snapshot: Snapshot) => void,
) => () => void;
export type MutableSourceGetVersionFn = (
source: $NonMaybeType<mixed>,
) => MutableSourceVersion;
export type MutableSource<Source: $NonMaybeType<mixed>> = {
_source: Source,
_getVersion: MutableSourceGetVersionFn,
// Tracks the version of this source at the time it was most recently read.
// Used to determine if a source is safe to read from before it has been subscribed to.
// Version number is only used during mount,
// since the mechanism for determining safety after subscription is expiration time.
//
// As a workaround to support multiple concurrent renderers,
// we categorize some renderers as primary and others as secondary.
// We only expect there to be two concurrent renderers at most:
// React Native (primary) and Fabric (secondary);
// React DOM (primary) and React ART (secondary).
// Secondary renderers store their context values on separate fields.
// We use the same approach for Context.
_workInProgressVersionPrimary: null | MutableSourceVersion,
_workInProgressVersionSecondary: null | MutableSourceVersion,
// DEV only
// Used to detect multiple renderers using the same mutable source.
_currentPrimaryRenderer?: Object | null,
_currentSecondaryRenderer?: Object | null,
// DEV only
// Used to detect side effects that update a mutable source during render.
// See https://github.com/facebook/react/issues/19948
_currentlyRenderingFiber?: Fiber | null,
_initialVersionAsOfFirstRender?: MutableSourceVersion | null,
};
// The subset of a Thenable required by things thrown by Suspense.
// This doesn't require a value to be passed to either handler.
export interface Wakeable {
then(onFulfill: () => mixed, onReject: () => mixed): void | Wakeable;
}
// The subset of a Promise that React APIs rely on. This resolves a value.
// This doesn't require a return value neither from the handler nor the
// then function.
experimental_use(promise) (#25084) * Internal `act`: Unwrapping resolved promises This update our internal implementation of `act` to support React's new behavior for unwrapping promises. Like we did with Scheduler, when something suspends, it will yield to the main thread so the microtasks can run, then continue in a new task. I need to implement the same behavior in the public version of `act`, but there are some additional considerations so I'll do that in a separate commit. * Move throwException to after work loop resumes throwException is the function that finds the nearest boundary and schedules it for a second render pass. We should only call it right before we unwind the stack — not if we receive an immediate ping and render the fiber again. This was an oversight in 8ef3a7c that I didn't notice because it happens to mostly work, anyway. What made me notice the mistake is that throwException also marks the entire render phase as suspended (RootDidSuspend or RootDidSuspendWithDelay), which is only supposed to be happen if we show a fallback. One consequence was that, in the RootDidSuspendWithDelay case, the entire commit phase was blocked, because that's the exit status we use to block a bad fallback from appearing. * Use expando to check whether promise has resolved Add a `status` expando to a thrown thenable to track when its value has resolved. In a later step, we'll also use `value` and `reason` expandos to track the resolved value. This is not part of the official JavaScript spec — think of it as an extension of the Promise API, or a custom interface that is a superset of Thenable. However, it's inspired by the terminology used by `Promise.allSettled`. The intent is that this will be a public API — Suspense implementations can set these expandos to allow React to unwrap the value synchronously without waiting a microtask. * Scaffolding for `experimental_use` hook Sets up a new experimental hook behind a feature flag, but does not implement it yet. * use(promise) Adds experimental support to Fiber for unwrapping the value of a promise inside a component. It is not yet implemented for Server Components, but that is planned. If promise has already resolved, the value can be unwrapped "immediately" without showing a fallback. The trick we use to implement this is to yield to the main thread (literally suspending the work loop), wait for the microtask queue to drain, then check if the promise resolved in the meantime. If so, we can resume the last attempted fiber without unwinding the stack. This functionality was implemented in previous commits. Another feature is that the promises do not need to be cached between attempts. Because we assume idempotent execution of components, React will track the promises that were used during the previous attempt and reuse the result. You shouldn't rely on this property, but during initial render it mostly just works. Updates are trickier, though, because if you used an uncached promise, we have no way of knowing whether the underlying data has changed, so we have to unwrap the promise every time. It will still work, but it's inefficient and can lead to unnecessary fallbacks if it happens during a discrete update. When we implement this for Server Components, this will be less of an issue because there are no updates in that environment. However, it's still better for performance to cache data requests, so the same principles largely apply. The intention is that this will eventually be the only supported way to suspend on arbitrary promises. Throwing a promise directly will be deprecated.
2022-08-26 02:12:07 +08:00
interface ThenableImpl<T> {
then(
onFulfill: (value: T) => mixed,
onReject: (error: mixed) => mixed,
): void | Wakeable;
}
interface UntrackedThenable<T> extends ThenableImpl<T> {
status?: void;
}
export interface PendingThenable<T> extends ThenableImpl<T> {
status: 'pending';
}
export interface FulfilledThenable<T> extends ThenableImpl<T> {
status: 'fulfilled';
value: T;
}
[Fabric] Use container node to toggle the visibility of Offscreen and Suspense trees (#21960) * Fix type of Offscreen props argument Fixes an oversight from a previous refactor. The fiber that wraps a Suspense component's children used to be a Fragment but now it's on Offscreen fiber, so its props type has changed. There's a special hydration path where I forgot to update this. This isn't observable because we don't ever end up rendering this particular fiber (because the Suspense boundary is in its fallback state) but we should fix it anyway to avoid a potential regression in the future. * Extract createOffscreenFromFiber logic ...into a new method called `createWorkInProgressOffscreenFiber`. Just for symmetry with `updateWorkInProgressOffscreenFiber`. Doesn't change any behavior. * [Fabric] Use container node to hide/show tree This changes how we hide and show the contents of Offscreen boundaries in the React Fabric renderer (persistent mode), and also Suspense boundaries which use the same feature.= The way it used to work was that when a boundary is hidden, in the complete phase, instead of calling the normal `cloneInstance` method inside `appendAllChildren`, we would call a forked method called `cloneHiddenInstance` for each of the nearest host nodes within the subtree. This design was largely based on how it works in React DOM (mutation mode), where instead of cloning the nearest host nodes, we mutate their `style.display` property. The motivation for doing it this way in React DOM was because there's no built-in browser API for hiding a collection of DOM nodes without affecting their layout. In Fabric, however, there is no such limitation, so we can instead wrap in an extra host node and apply a hidden style. The immediate motivation for this change is that Fabric on Android has a view pooling mechanism for instances that relies on the assumption that a current Fiber that is cloned and replaced by a new Fiber will never appear in a future commit. When this assumption is broken, it may cause crashes. In the current implementation, that can indeed happen when a node that was previously hidden is toggled back to visible. Although this change sidesteps the issue, we may introduce in other features in the future that would benefit from being able to revert back to an older node without cloning it again, such as animations. The way I've implemented this is to insert an additional HostComponent fiber as the child of each OffscreenComponent. The extra fiber is not ideal — the way I'd prefer to do it is to attach the host instance to the OffscreenComponent. However, the native Fabric implementation currently expects a 1:1 correspondence between HostComponents and host instances, so I've deferred that optimization to a future PR to derisk fixing the Fabric pooling crash. I left a TODO in the host config with a description of the remaining steps, but this alone should be sufficient to unblock.
2021-07-27 04:17:08 +08:00
experimental_use(promise) (#25084) * Internal `act`: Unwrapping resolved promises This update our internal implementation of `act` to support React's new behavior for unwrapping promises. Like we did with Scheduler, when something suspends, it will yield to the main thread so the microtasks can run, then continue in a new task. I need to implement the same behavior in the public version of `act`, but there are some additional considerations so I'll do that in a separate commit. * Move throwException to after work loop resumes throwException is the function that finds the nearest boundary and schedules it for a second render pass. We should only call it right before we unwind the stack — not if we receive an immediate ping and render the fiber again. This was an oversight in 8ef3a7c that I didn't notice because it happens to mostly work, anyway. What made me notice the mistake is that throwException also marks the entire render phase as suspended (RootDidSuspend or RootDidSuspendWithDelay), which is only supposed to be happen if we show a fallback. One consequence was that, in the RootDidSuspendWithDelay case, the entire commit phase was blocked, because that's the exit status we use to block a bad fallback from appearing. * Use expando to check whether promise has resolved Add a `status` expando to a thrown thenable to track when its value has resolved. In a later step, we'll also use `value` and `reason` expandos to track the resolved value. This is not part of the official JavaScript spec — think of it as an extension of the Promise API, or a custom interface that is a superset of Thenable. However, it's inspired by the terminology used by `Promise.allSettled`. The intent is that this will be a public API — Suspense implementations can set these expandos to allow React to unwrap the value synchronously without waiting a microtask. * Scaffolding for `experimental_use` hook Sets up a new experimental hook behind a feature flag, but does not implement it yet. * use(promise) Adds experimental support to Fiber for unwrapping the value of a promise inside a component. It is not yet implemented for Server Components, but that is planned. If promise has already resolved, the value can be unwrapped "immediately" without showing a fallback. The trick we use to implement this is to yield to the main thread (literally suspending the work loop), wait for the microtask queue to drain, then check if the promise resolved in the meantime. If so, we can resume the last attempted fiber without unwinding the stack. This functionality was implemented in previous commits. Another feature is that the promises do not need to be cached between attempts. Because we assume idempotent execution of components, React will track the promises that were used during the previous attempt and reuse the result. You shouldn't rely on this property, but during initial render it mostly just works. Updates are trickier, though, because if you used an uncached promise, we have no way of knowing whether the underlying data has changed, so we have to unwrap the promise every time. It will still work, but it's inefficient and can lead to unnecessary fallbacks if it happens during a discrete update. When we implement this for Server Components, this will be less of an issue because there are no updates in that environment. However, it's still better for performance to cache data requests, so the same principles largely apply. The intention is that this will eventually be the only supported way to suspend on arbitrary promises. Throwing a promise directly will be deprecated.
2022-08-26 02:12:07 +08:00
export interface RejectedThenable<T> extends ThenableImpl<T> {
status: 'rejected';
reason: mixed;
}
export type Thenable<T> =
| UntrackedThenable<T>
| PendingThenable<T>
| FulfilledThenable<T>
| RejectedThenable<T>;
[Fabric] Use container node to toggle the visibility of Offscreen and Suspense trees (#21960) * Fix type of Offscreen props argument Fixes an oversight from a previous refactor. The fiber that wraps a Suspense component's children used to be a Fragment but now it's on Offscreen fiber, so its props type has changed. There's a special hydration path where I forgot to update this. This isn't observable because we don't ever end up rendering this particular fiber (because the Suspense boundary is in its fallback state) but we should fix it anyway to avoid a potential regression in the future. * Extract createOffscreenFromFiber logic ...into a new method called `createWorkInProgressOffscreenFiber`. Just for symmetry with `updateWorkInProgressOffscreenFiber`. Doesn't change any behavior. * [Fabric] Use container node to hide/show tree This changes how we hide and show the contents of Offscreen boundaries in the React Fabric renderer (persistent mode), and also Suspense boundaries which use the same feature.= The way it used to work was that when a boundary is hidden, in the complete phase, instead of calling the normal `cloneInstance` method inside `appendAllChildren`, we would call a forked method called `cloneHiddenInstance` for each of the nearest host nodes within the subtree. This design was largely based on how it works in React DOM (mutation mode), where instead of cloning the nearest host nodes, we mutate their `style.display` property. The motivation for doing it this way in React DOM was because there's no built-in browser API for hiding a collection of DOM nodes without affecting their layout. In Fabric, however, there is no such limitation, so we can instead wrap in an extra host node and apply a hidden style. The immediate motivation for this change is that Fabric on Android has a view pooling mechanism for instances that relies on the assumption that a current Fiber that is cloned and replaced by a new Fiber will never appear in a future commit. When this assumption is broken, it may cause crashes. In the current implementation, that can indeed happen when a node that was previously hidden is toggled back to visible. Although this change sidesteps the issue, we may introduce in other features in the future that would benefit from being able to revert back to an older node without cloning it again, such as animations. The way I've implemented this is to insert an additional HostComponent fiber as the child of each OffscreenComponent. The extra fiber is not ideal — the way I'd prefer to do it is to attach the host instance to the OffscreenComponent. However, the native Fabric implementation currently expects a 1:1 correspondence between HostComponents and host instances, so I've deferred that optimization to a future PR to derisk fixing the Fabric pooling crash. I left a TODO in the host config with a description of the remaining steps, but this alone should be sufficient to unblock.
2021-07-27 04:17:08 +08:00
export type OffscreenMode =
| 'hidden'
| 'unstable-defer-without-hiding'
| 'visible'
| 'manual';
[DevTools][Transition Tracing] onTransitionComplete and onTransitionStart implmentation (#23313) * add transition name to startTransition Add a transitionName to start transition, store the transition start time and name in the batch config, and pass it to the root on render * Transition Tracing Types and Consts * Root begin work The root operates as a tracing marker that has all transitions on it. This PR only tested the root with one transition so far - Store transitions in memoizedState. Do this in updateHostRoot AND attemptEarlyBailoutIfNoScheduledUpdate. We need to do this in the latter part because even if the root itself doesn't have an update, it could still have new transitions in its transitionLanes map that we need to process. * Transition Tracing commit phase - adds a module scoped pending transition callbacks object that contains all transition callbacks that have not yet been processed. This contains all callbacks before the next paint occurs. - Add code in the mutation phase to: * For the root, if there are transitions that were initialized during this commit in the root transition lanes map, add a transition start call to the pending transition callbacks object. Then, remove the transitions from the root transition lanes map. * For roots, in the commit phase, add a transition complete call We add this code in the mutation phase because we can't add it to the passive phase because then the paint might have occurred before we even know which callbacks to call * Process Callbacks after paint At the end of the commit phase, call scheduleTransitionCallbacks to schedule all pending transition callbacks to be called after paint. Then clear the callbacks
2022-02-25 06:28:18 +08:00
export type StartTransitionOptions = {
[DevTools][Transition Tracing] onTransitionComplete and onTransitionStart implmentation (#23313) * add transition name to startTransition Add a transitionName to start transition, store the transition start time and name in the batch config, and pass it to the root on render * Transition Tracing Types and Consts * Root begin work The root operates as a tracing marker that has all transitions on it. This PR only tested the root with one transition so far - Store transitions in memoizedState. Do this in updateHostRoot AND attemptEarlyBailoutIfNoScheduledUpdate. We need to do this in the latter part because even if the root itself doesn't have an update, it could still have new transitions in its transitionLanes map that we need to process. * Transition Tracing commit phase - adds a module scoped pending transition callbacks object that contains all transition callbacks that have not yet been processed. This contains all callbacks before the next paint occurs. - Add code in the mutation phase to: * For the root, if there are transitions that were initialized during this commit in the root transition lanes map, add a transition start call to the pending transition callbacks object. Then, remove the transitions from the root transition lanes map. * For roots, in the commit phase, add a transition complete call We add this code in the mutation phase because we can't add it to the passive phase because then the paint might have occurred before we even know which callbacks to call * Process Callbacks after paint At the end of the commit phase, call scheduleTransitionCallbacks to schedule all pending transition callbacks to be called after paint. Then clear the callbacks
2022-02-25 06:28:18 +08:00
name?: string,
};
experimental_use(promise) (#25084) * Internal `act`: Unwrapping resolved promises This update our internal implementation of `act` to support React's new behavior for unwrapping promises. Like we did with Scheduler, when something suspends, it will yield to the main thread so the microtasks can run, then continue in a new task. I need to implement the same behavior in the public version of `act`, but there are some additional considerations so I'll do that in a separate commit. * Move throwException to after work loop resumes throwException is the function that finds the nearest boundary and schedules it for a second render pass. We should only call it right before we unwind the stack — not if we receive an immediate ping and render the fiber again. This was an oversight in 8ef3a7c that I didn't notice because it happens to mostly work, anyway. What made me notice the mistake is that throwException also marks the entire render phase as suspended (RootDidSuspend or RootDidSuspendWithDelay), which is only supposed to be happen if we show a fallback. One consequence was that, in the RootDidSuspendWithDelay case, the entire commit phase was blocked, because that's the exit status we use to block a bad fallback from appearing. * Use expando to check whether promise has resolved Add a `status` expando to a thrown thenable to track when its value has resolved. In a later step, we'll also use `value` and `reason` expandos to track the resolved value. This is not part of the official JavaScript spec — think of it as an extension of the Promise API, or a custom interface that is a superset of Thenable. However, it's inspired by the terminology used by `Promise.allSettled`. The intent is that this will be a public API — Suspense implementations can set these expandos to allow React to unwrap the value synchronously without waiting a microtask. * Scaffolding for `experimental_use` hook Sets up a new experimental hook behind a feature flag, but does not implement it yet. * use(promise) Adds experimental support to Fiber for unwrapping the value of a promise inside a component. It is not yet implemented for Server Components, but that is planned. If promise has already resolved, the value can be unwrapped "immediately" without showing a fallback. The trick we use to implement this is to yield to the main thread (literally suspending the work loop), wait for the microtask queue to drain, then check if the promise resolved in the meantime. If so, we can resume the last attempted fiber without unwinding the stack. This functionality was implemented in previous commits. Another feature is that the promises do not need to be cached between attempts. Because we assume idempotent execution of components, React will track the promises that were used during the previous attempt and reuse the result. You shouldn't rely on this property, but during initial render it mostly just works. Updates are trickier, though, because if you used an uncached promise, we have no way of knowing whether the underlying data has changed, so we have to unwrap the promise every time. It will still work, but it's inefficient and can lead to unnecessary fallbacks if it happens during a discrete update. When we implement this for Server Components, this will be less of an issue because there are no updates in that environment. However, it's still better for performance to cache data requests, so the same principles largely apply. The intention is that this will eventually be the only supported way to suspend on arbitrary promises. Throwing a promise directly will be deprecated.
2022-08-26 02:12:07 +08:00
2022-09-08 01:09:42 +08:00
export type Usable<T> = Thenable<T> | ReactContext<T>;