Skip to content

Commit

Permalink
Handle loading returning undefined (#40938)
Browse files Browse the repository at this point in the history
Since React 18 returning `undefined` from components is allowed which renders to `undefined` in the RSC response so we need a separate prop to know if the loading boundary was provided.

Thanks to @finn-orsini who reported this problem.



## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
  • Loading branch information
timneutkens committed Sep 27, 2022
1 parent 406d69d commit a92a3b6
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
9 changes: 7 additions & 2 deletions packages/next/client/components/layout-router.client.tsx
Expand Up @@ -278,11 +278,14 @@ export function InnerLayoutRouter({
function LoadingBoundary({
children,
loading,
hasLoading,
}: {
children: React.ReactNode
loading?: React.ReactNode
hasLoading: boolean
}): JSX.Element {
if (loading) {
if (hasLoading) {
// @ts-expect-error TODO-APP: React.Suspense fallback type is wrong
return <React.Suspense fallback={loading}>{children}</React.Suspense>
}

Expand Down Expand Up @@ -450,6 +453,7 @@ export default function OuterLayoutRouter({
childProp,
error,
loading,
hasLoading,
template,
notFound,
rootLayoutIncluded,
Expand All @@ -460,6 +464,7 @@ export default function OuterLayoutRouter({
error: ErrorComponent
template: React.ReactNode
loading: React.ReactNode | undefined
hasLoading: boolean
notFound: React.ReactNode | undefined
rootLayoutIncluded: boolean
}) {
Expand Down Expand Up @@ -510,7 +515,7 @@ export default function OuterLayoutRouter({
key={preservedSegment}
value={
<ErrorBoundary errorComponent={error}>
<LoadingBoundary loading={loading}>
<LoadingBoundary hasLoading={hasLoading} loading={loading}>
<NotFoundBoundary notFound={notFound}>
<RedirectBoundary>
<InnerLayoutRouter
Expand Down
3 changes: 3 additions & 0 deletions packages/next/server/app-render.tsx
Expand Up @@ -942,6 +942,7 @@ export async function renderToHTMLOrFlight(
parallelRouterKey={parallelRouteKey}
segmentPath={createSegmentPath(currentSegmentPath)}
loading={Loading ? <Loading /> : undefined}
hasLoading={Boolean(Loading)}
error={ErrorComponent}
template={
<Template>
Expand Down Expand Up @@ -982,6 +983,8 @@ export async function renderToHTMLOrFlight(
segmentPath={segmentPath}
error={ErrorComponent}
loading={Loading ? <Loading /> : undefined}
// TODO-APP: Add test for loading returning `undefined`. This currently can't be tested as the `webdriver()` tab will wait for the full page to load before returning.
hasLoading={Boolean(Loading)}
template={
<Template>
<RenderFromTemplateContext />
Expand Down

0 comments on commit a92a3b6

Please sign in to comment.