facebook/react

Bug: Nested Suspense Fallback Not Triggering for Child Component

LeoAnt02 opened this issue · 1 comments

React version: 18

Steps To Reproduce
1. Create a component with nested boundaries:
• Parent wraps a parent component (DataParent) with a fallback.
• Child wraps a child component (DataChild) with its own fallback.
2. Pass data-fetching promises to both parent and child components using React.use() or async/await to simulate Suspense-compatible data fetching.
3. Ensure the child fallback is rendered only when the parent data is resolved but the child data is still loading.

Here’s a sample implementation:

"use client";

import * as React from "react";
import { Suspense } from "react";

interface ParentProps {
  dataPromise: Promise<{ items: string[] }>;
  children?: React.ReactNode;
}

function Parent({ dataPromise, children }: ParentProps) {
  const data = React.use(dataPromise);

  return (
    <div className="parent">
      <h2>Parent Data</h2>
      <ul>
        {data.items.map((item, idx) => (
          <li key={idx}>{item}</li>
        ))}
      </ul>
      {children}
    </div>
  );
}

interface ChildProps {
  detailPromise: Promise<{ detail: string }>;
}

async function Child({ detailPromise }: ChildProps) {
  const detail = await detailPromise;

  return (
    <div className="child">
      <h3>Child Detail</h3>
      <p>{detail.detail}</p>
    </div>
  );
}

export default function SuspenseExamplePage() {
  const parentDataPromise = new Promise<{ items: string[] }>((resolve) => {
    setTimeout(() => resolve({ items: ["Item 1", "Item 2"] }), 1000);
  });

  const childDataPromise = new Promise<{ detail: string }>((resolve) => {
    setTimeout(() => resolve({ detail: "Detailed information" }), 2000);
  });

  return (
    <Suspense fallback={<div>Loading Parent...</div>}>
      <Parent dataPromise={parentDataPromise}>
        <Suspense fallback={<div>Loading Child...</div>}>
          <Child detailPromise={childDataPromise} />
        </Suspense>
      </Parent>
    </Suspense>
  );
}

The current behavior

When loading the parent and child components:
• The fallback for the parent ("Loading Parent...") renders as expected while the parent data is loading.
• After the parent data resolves, the child fallback ("Loading Child...") does not trigger.
• Instead, the parent content renders immediately, and the child fallback is skipped altogether.

The expected behavior

When the parent data resolves and the child data is still loading:
• The parent content should render normally.
• The child fallback ("Loading Child...") should render until the child data is ready.

Can you provide a cloneable repro? If you're just using client-side React, you can use https://react.new