Support sync thenables for lazy() (#14626)
* Support sync thenables for lazy() * Don't commit twice
Dan Abramov committed
Jan 18, 2019 at 21:16 UTC
9120f6c2d82049b0c927e429f9fb8b1e29c15f59
2 files changed
+22
-1
packages/react-reconciler/src/ReactFiberLazyComponent.js
+5
-1
@@ -47,6 +47,7 @@ export function readLazyComponentType<T>(lazyComponent: LazyComponent<T>): T {
47
lazyComponent._status = Pending;
48
const ctor = lazyComponent._ctor;
49
const thenable = ctor();
50
+ lazyComponent._result = thenable;
51
thenable.then(
52
moduleObject => {
53
if (lazyComponent._status === Pending) {
@@ -73,7 +74,10 @@ export function readLazyComponentType<T>(lazyComponent: LazyComponent<T>): T {
74
}
75
},
76
);
76
- lazyComponent._result = thenable;
77
+ // Check if it resolved synchronously
78
+ if (lazyComponent._status === Resolved) {
79
+ return lazyComponent._result;
80
+ }
81
throw thenable;
82
}
83
}
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+17
@@ -61,6 +61,23 @@ describe('ReactLazy', () => {
61
expect(root).toMatchRenderedOutput('Hi again');
62
});
63
64
+ it('can resolve synchronously without suspending', async () => {
65
+ const LazyText = lazy(() => ({
66
+ then(cb) {
67
+ cb({default: Text});
68
+ },
69
+ }));
70
+
71
+ const root = ReactTestRenderer.create(
72
+ <Suspense fallback={<Text text="Loading..." />}>
73
+ <LazyText text="Hi" />
74
+ </Suspense>,
75
+ );
76
+
77
+ expect(ReactTestRenderer).toHaveYielded(['Hi']);
78
+ expect(root).toMatchRenderedOutput('Hi');
79
+ });
80
+
81
it('multiple lazy components', async () => {
82
function Foo() {
83
return <Text text="Foo" />;