Skip to content

Bug: renderToPipeableStream doesn't initiate streaming if the first node is a Fragment until the promise in Suspense resolves #33352

@roggc

Description

@roggc

renderToPipeableStream behaves differently if the first element is a div or a Fragment. With a div it behaves well, it starts streamming just ahead, without waiting for the promise in Suspense to fullfill. With a Fragment it doesn't behaves well, it waits for the promise in Suspense to resolve to start streamming.

React version: 19.1.0

Steps To Reproduce

  1. Execute the code shown below with node, first do renderToStream("div"), and then do renderToStream(React.Fragment)
  2. You will see the difference in behaviour. First case is good, second not.

Link to code example:

const { renderToPipeableStream } = require("react-dom/server");
const React = require("react");

function renderToStream(Component) {
  const stream = renderToPipeableStream(
    React.createElement(
      Component,
      null,
      React.createElement(
        React.Suspense,
        null,
        new Promise((resolve) => setTimeout(resolve, 4000))
      )
    ),
    {
      onShellReady() {
        stream.pipe(process.stdout);
      },
    }
  );
}

renderToStream("div"); // OK
renderToStream(React.Fragment); // NOT OK

The current behavior

The current behavior is WRONG with React.Fragment. Enforces users to use an unnecessary parent div if they don't want to get stuck with a blank screen.

The expected behavior

The expected behavior is there is no difference in behaviour with React.Fragment and div. React.Fragment should start streamming immediately, as div does, and not wait for the promise in Suspense to resolve.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions