react/packages/shared/ReactLazyComponent.js
Andrew Clark d9659e499e
Lazy components must use React.lazy (#13885)
Removes support for using arbitrary promises as the type of a React
element. Instead, promises must be wrapped in React.lazy. This gives us
flexibility later if we need to change the protocol.

The reason is that promises do not provide a way to call their
constructor multiple times. For example:

const promiseForA = new Promise(resolve => {
  fetchA(a => resolve(a));
});

Given a reference to `promiseForA`, there's no way to call `fetchA`
again. Calling `then` on the promise doesn't run the constructor again;
it only attaches another listener.

In the future we will likely introduce an API like `React.eager` that
is similar to `lazy` but eagerly calls the constructor. That gives us
the ability to call the constructor multiple times. E.g. to increase
the priority, or to retry if the first operation failed.
2018-10-18 19:57:12 -07:00

43 lines
1011 B
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
export type Thenable<T, R> = {
then(resolve: (T) => mixed, reject: (mixed) => mixed): R,
};
export type LazyComponent<T> = {
$$typeof: Symbol | number,
_ctor: () => Thenable<T, mixed>,
_status: 0 | 1 | 2,
_result: any,
};
type ResolvedLazyComponentThenable<T> = {
$$typeof: Symbol | number,
_ctor: () => Thenable<T, mixed>,
_status: 1,
_result: any,
};
export const Pending = 0;
export const Resolved = 1;
export const Rejected = 2;
export function getResultFromResolvedLazyComponent<T>(
lazyComponent: ResolvedLazyComponentThenable<T>,
): T {
return lazyComponent._result;
}
export function refineResolvedLazyComponent<T>(
lazyComponent: LazyComponent<T>,
): ResolvedLazyComponentThenable<T> | null {
return lazyComponent._status === Resolved ? lazyComponent._result : null;
}