Skip to content

Bug: Incorrect Hydration Mismatch Detection during Suspense - "Hydration failed because the initial UI does not match what was rendered on the server." #24384

Closed
@xiel

Description

@xiel

React version: 18.0.0

Steps To Reproduce

  1. Add a Suspense Boundary
  2. Add a component that will suspend to load some data (faked).
  3. Render at least one sibling component after the suspending component.
  4. Render server-side using renderToPipeableStream()
  5. Render client-side using hydrateRoot()

Reproductions in CodeSandbox:

<>
  <h4>This headline hydrates fine. </h4>
  <SomethingA />{/* Will suspend on client and server */}
  <h3>💥 This element after the suspending Component triggers an error (only in development).</h3>
</>

The current behavior

  • The sibling component following the suspending component is incorrectly seen as a hydration mismatch.
  • Console will show errors (and Next.js will show big error overlay):
Warning: Expected server HTML to contain a matching <h3> in <div>.
    at h3
    at IndexPage
    at Suspense
    at App (webpack-internal:///./pages/_app.js:42:27)
    at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:20638)
    at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:23179)
    at Container (webpack-internal:///./node_modules/next/dist/client/index.js:323:9)
    at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:825:26)
    at Root (webpack-internal:///./node_modules/next/dist/client/index.js:949:27)
Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
    at throwOnHydrationMismatch (react-dom.development.js?ac89:14344:1)
    at tryToClaimNextHydratableInstance (react-dom.development.js?ac89:14372:1)
    at updateHostComponent$1 (react-dom.development.js?ac89:20636:1)
    at beginWork (react-dom.development.js?ac89:22373:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js?ac89:4157:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?ac89:4206:1)
    at invokeGuardedCallback (react-dom.development.js?ac89:4270:1)
  • Depending on the location of the suspending component and their siblings, there are errors or no errors at all. When the suspending component is the last component, there are no errors logged.
  • Error can be suppressed by wrapping the suspending component in a Suspense boundary directly

The expected behavior

  • I expect to be able to use the same fetching mechanism using suspense on server and client in React v18.
    OR
  • If this is unsupported usage, the errors should be more clear and consistent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    React 18Bug reports, questions, and general feedback about React 18Type: Bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions