react/packages/shared/ReactLazyComponent.js
Sebastian Markbåge fa03206ee4
Remove _ctor field from Lazy components (#18217)
* This type is all wrong and nothing cares because it's all any

* Refine Flow types of Lazy Components

We can type each condition.

* Remove _ctor field from Lazy components

This field is not needed because it's only used before we've initialized,
and we don't have anything else to store before we've initialized.

* Check for _ctor in case it's an older isomorphic that created it

We try not to break across minors but it's no guarantee.

* Move types and constants from shared to isomorphic

The "react" package owns the data structure of the Lazy component. It
creates it and decides how any downstream renderer may use it.

* Move constants to shared

Apparently we can't depend on react/src/ because the whole package is
considered "external" as far as rollup is concerned.
2020-03-04 20:52:48 -08:00

75 lines
2.2 KiB
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
*/
import type {
PendingLazyComponent,
ResolvedLazyComponent,
RejectedLazyComponent,
LazyComponent,
} from 'react/src/ReactLazy';
import {
Uninitialized,
Pending,
Resolved,
Rejected,
} from './ReactLazyStatusTags';
export function refineResolvedLazyComponent<T>(
lazyComponent: LazyComponent<T>,
): T | null {
return lazyComponent._status === Resolved ? lazyComponent._result : null;
}
export function initializeLazyComponentType(
lazyComponent: LazyComponent<any>,
): void {
if (lazyComponent._status === Uninitialized) {
let ctor = lazyComponent._result;
if (!ctor) {
// TODO: Remove this later. THis only exists in case you use an older "react" package.
ctor = ((lazyComponent: any)._ctor: typeof ctor);
}
const thenable = ctor();
// Transition to the next state.
const pending: PendingLazyComponent<any> = (lazyComponent: any);
pending._status = Pending;
pending._result = thenable;
thenable.then(
moduleObject => {
if (lazyComponent._status === Pending) {
const defaultExport = moduleObject.default;
if (__DEV__) {
if (defaultExport === undefined) {
console.error(
'lazy: Expected the result of a dynamic import() call. ' +
'Instead received: %s\n\nYour code should look like: \n ' +
"const MyComponent = lazy(() => import('./MyComponent'))",
moduleObject,
);
}
}
// Transition to the next state.
const resolved: ResolvedLazyComponent<any> = (lazyComponent: any);
resolved._status = Resolved;
resolved._result = defaultExport;
}
},
error => {
if (lazyComponent._status === Pending) {
// Transition to the next state.
const rejected: RejectedLazyComponent = (lazyComponent: any);
rejected._status = Rejected;
rejected._result = error;
}
},
);
}
}