From 0695c13172fe7f897fbb8718ce23534e765cf011 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Fri, 18 Jan 2019 10:38:19 +0000 Subject: [PATCH 1/2] Support sync thenables for lazy() --- .../src/ReactFiberLazyComponent.js | 5 ++++- .../src/__tests__/ReactLazy-test.internal.js | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactFiberLazyComponent.js b/packages/react-reconciler/src/ReactFiberLazyComponent.js index cae98e4a1f599..2b9db1d7947a9 100644 --- a/packages/react-reconciler/src/ReactFiberLazyComponent.js +++ b/packages/react-reconciler/src/ReactFiberLazyComponent.js @@ -73,7 +73,10 @@ export function readLazyComponentType(lazyComponent: LazyComponent): T { } }, ); - lazyComponent._result = thenable; + // Don't race with a sync thenable + if (lazyComponent._status === Pending) { + lazyComponent._result = thenable; + } throw thenable; } } diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js index 80639c8831ba6..fac75f6f594d7 100644 --- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js @@ -61,6 +61,23 @@ describe('ReactLazy', () => { expect(root).toMatchRenderedOutput('Hi again'); }); + it('can resolve synchronously without suspending', async () => { + const LazyText = lazy(() => ({ + then(cb) { + cb({default: Text}); + }, + })); + + const root = ReactTestRenderer.create( + }> + + , + ); + + expect(ReactTestRenderer).toHaveYielded(['Loading...', 'Hi']); + expect(root).toMatchRenderedOutput('Hi'); + }); + it('multiple lazy components', async () => { function Foo() { return ; From 7f9f85291fe8868f5fa9c3765de1469930977adb Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Fri, 18 Jan 2019 20:43:03 +0000 Subject: [PATCH 2/2] Don't commit twice --- packages/react-reconciler/src/ReactFiberLazyComponent.js | 7 ++++--- .../src/__tests__/ReactLazy-test.internal.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberLazyComponent.js b/packages/react-reconciler/src/ReactFiberLazyComponent.js index 2b9db1d7947a9..179262fa449c8 100644 --- a/packages/react-reconciler/src/ReactFiberLazyComponent.js +++ b/packages/react-reconciler/src/ReactFiberLazyComponent.js @@ -47,6 +47,7 @@ export function readLazyComponentType(lazyComponent: LazyComponent): T { lazyComponent._status = Pending; const ctor = lazyComponent._ctor; const thenable = ctor(); + lazyComponent._result = thenable; thenable.then( moduleObject => { if (lazyComponent._status === Pending) { @@ -73,9 +74,9 @@ export function readLazyComponentType(lazyComponent: LazyComponent): T { } }, ); - // Don't race with a sync thenable - if (lazyComponent._status === Pending) { - lazyComponent._result = thenable; + // Check if it resolved synchronously + if (lazyComponent._status === Resolved) { + return lazyComponent._result; } throw thenable; } diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js index fac75f6f594d7..8fb4210f92923 100644 --- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js @@ -74,7 +74,7 @@ describe('ReactLazy', () => { , ); - expect(ReactTestRenderer).toHaveYielded(['Loading...', 'Hi']); + expect(ReactTestRenderer).toHaveYielded(['Hi']); expect(root).toMatchRenderedOutput('Hi'); });