Fix loading navigation with metadata and prefetch (#66447)
### What & Why Fixes NEXT-3498 Fixed loading shows up and disappear during client navigation, when you defined `prefetch` is enabled and slow `generateMetadata` is defined. In #64532, where in layout-router, we removed the place of infinite suspense, adding it back so that the app can still remain suspensy during navigation. #### Behavior before fix Prefetch -> Link Navigation -> Show `loading.js` -> RSC payload fetched (no page content) -> the page content will display later when the promise is resolved #### Behavior after the fix Prefetch -> Link Navigation -> Show `loading.js` -> RSC payload fetched -> suspensy page content still triggering `loading.js` -> display the resolved page content when the promise is resolved --------- Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
This commit is contained in:
parent
b911485454
commit
60ab8f6363
3 changed files with 17 additions and 17 deletions
|
@ -450,10 +450,10 @@ function InnerLayoutRouter({
|
|||
// It's important that we mark this as resolved, in case this branch is replayed, we don't want to continously re-apply
|
||||
// the patch to the tree.
|
||||
childNode.lazyDataResolved = true
|
||||
|
||||
// Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered.
|
||||
use(unresolvedThenable) as never
|
||||
}
|
||||
// Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered.
|
||||
// A falsey `resolvedRsc` indicates missing data -- we should not commit that branch, and we need to wait for the data to arrive.
|
||||
use(unresolvedThenable) as never
|
||||
}
|
||||
|
||||
// We use `useDeferredValue` to handle switching between the prefetched and
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
'use client'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export default function Loading() {
|
||||
useEffect(() => {
|
||||
window.shownLoading = true
|
||||
}, [])
|
||||
return <div id="loading">Loading</div>
|
||||
}
|
||||
|
|
|
@ -864,16 +864,22 @@ describe('app dir - navigation', () => {
|
|||
it('should render the final state of the page with correct metadata', async () => {
|
||||
const browser = await next.browser('/metadata-await-promise')
|
||||
|
||||
await browser
|
||||
.elementByCss("[href='/metadata-await-promise/nested']")
|
||||
.click()
|
||||
// dev doesn't trigger the loading boundary as it's not prefetched
|
||||
if (isNextDev) {
|
||||
await browser
|
||||
.elementByCss("[href='/metadata-await-promise/nested']")
|
||||
.click()
|
||||
} else {
|
||||
const loadingText = await browser
|
||||
.elementByCss("[href='/metadata-await-promise/nested']")
|
||||
.click()
|
||||
.waitForElementByCss('#loading')
|
||||
.text()
|
||||
|
||||
expect(loadingText).toBe('Loading')
|
||||
}
|
||||
|
||||
await retry(async () => {
|
||||
// dev doesn't trigger the loading boundary as it's not prefetched
|
||||
if (!isNextDev) {
|
||||
expect(await browser.eval(`window.shownLoading`)).toBe(true)
|
||||
}
|
||||
|
||||
expect(await browser.elementById('page-content').text()).toBe('Content')
|
||||
|
||||
expect(await browser.elementByCss('title').text()).toBe('Async Title')
|
||||
|
|
Loading…
Reference in a new issue