Skip to content

Commit 2b1dcd0

Browse files
author
Sidhu Alluri
committed
fix: lazy components suspending unnecessarily when already preloaded by loadableReady
1 parent 18544de commit 2b1dcd0

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

packages/component/src/createLoadable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ function createLoadable({
312312
} = this.props
313313
const { error, loading, result } = this.state
314314

315-
if (options.suspense) {
315+
if (options.suspense && loading) {
316316
const cachedPromise = this.getCache() || this.loadAsync()
317317
if (cachedPromise.status === STATUS_PENDING) {
318318
throw this.loadAsync()

packages/component/src/loadable.test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,55 @@ describe('#lazy', () => {
359359

360360
await wait(() => expect(container).toHaveTextContent('loaded'))
361361
})
362+
363+
it('should not suspend when component is preloaded with lazy', async () => {
364+
const ContentComponent = () => 'loaded'
365+
const ContentComponentModule = { default: ContentComponent }
366+
367+
// Simulate a preloaded component via chunkExtractor and loadableReady
368+
// This replicates the transformed output of the babel plugin constructor
369+
const Component = lazy({
370+
chunkName() { return 'chunkName' },
371+
isReady() { return true },
372+
requireSync() { return ContentComponentModule },
373+
requireAsync() { return Promise.resolve(ContentComponentModule) },
374+
resolve() { return ContentComponent },
375+
})
376+
377+
const { container } = render(
378+
<React.Suspense fallback="progress">
379+
<Component />
380+
</React.Suspense>,
381+
)
382+
expect(container).toHaveTextContent('loaded')
383+
expect(container).not.toHaveTextContent('progress')
384+
})
385+
386+
387+
it('should suspend when component is not preloaded with lazy', async () => {
388+
const ContentComponent = () => 'loaded'
389+
const ContentComponentModule = { default: ContentComponent }
390+
391+
// Simulate a non-preloaded component via chunkExtractor and loadableReady
392+
// This replicates the transformed output of the babel plugin constructor
393+
const Component = lazy({
394+
chunkName() { return 'chunkName' },
395+
isReady() { return false },
396+
requireSync() { return ContentComponentModule },
397+
requireAsync() { return Promise.resolve(ContentComponentModule) },
398+
resolve() { return ContentComponent },
399+
})
400+
401+
const { container } = render(
402+
<React.Suspense fallback="progress">
403+
<Component />
404+
</React.Suspense>,
405+
)
406+
expect(container).toHaveTextContent('progress')
407+
expect(container).not.toHaveTextContent('loaded')
408+
await wait(() => expect(container).toHaveTextContent('loaded'))
409+
expect(container).not.toHaveTextContent('progress')
410+
})
362411
})
363412

364413
describe('#loadable.lib', () => {

0 commit comments

Comments
 (0)