Skip to content

Bug: React.use inside React.lazy-ed component returns other React.use value on SSR #33937

@hi-ogawa

Description

@hi-ogawa

React version: 19.1.0, 19.2.0-canary-dffacc7b-20250717

Steps To Reproduce

Run a following code:

// [Component Tree]
// 
// Component1 -> use(promise1)
//   Component2Lazy
//     COmponent2 -> use(promise2)

import React from "react";
import ReactDOMServer from "react-dom/server.edge";

const promise1 = Promise.resolve("value1");
const promise2 = Promise.resolve("value2");

function Component1() {
  const data = React.use(promise1);
  console.log("[Component1] React.use(promise1) =", data);
  return React.createElement(
    "div",
    null,
    `Component1: ${data}`,
    React.createElement(Component2Lazy),
  );
}

function Component2() {
  const data = React.use(promise2);
  console.log("[Component2] React.use(promise2) =", data);
  return React.createElement("div", null, `Component2: ${data}`);
}

const Component2Lazy = React.lazy(async () => ({ default: Component2 }));

function App() {
  return React.createElement("div", null, React.createElement(Component1));
}

async function main() {
  console.log("react", React.version);
  console.log("react-dom", ReactDOMServer.version);
  try {
    const stream = await ReactDOMServer.renderToReadableStream(React.createElement(App));
    let html = "";
    await stream.pipeThrough(new TextDecoderStream()).pipeTo(
      new WritableStream({
        write(chunk) {
          html += chunk;
        },
      }),
    );
    console.log("HTML output:", html);
  } catch (error) {
    console.error("Error:", error);
  }
}

main();

Link to code example:

The current behavior

I also checked 19.2.0-canary-dffacc7b-20250717 showing the same behavior.

$ node index.js
react 19.1.0
react-dom 19.1.0
[Component1] React.use(promise1) = value1
[Component2] React.use(promise2) = value1    👈👈👈 `value2` is expected
HTML output: <div><div>Component1: value1<div>Component2: value1</div></div></div>

The expected behavior

$ node index.js
react 19.1.0
react-dom 19.1.0
[Component1] React.use(promise1) = value1
[Component2] React.use(promise2) = value2 
HTML output: <div><div>Component1: value1<div>Component2: value2</div></div></div>

(context)

We found a issue where multiple React.use calls in different components are mixed up on Waku wakujs/waku#1496. I haven't fully tied two issues, but I suspect client reference becoming implicitly being lazy component during ssr is causing a similar behavior.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions