next.js icon indicating copy to clipboard operation
next.js copied to clipboard

React.useId() usage results in hydration mismatch

Open rijk opened this issue 3 years ago • 3 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

next info:
    Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:52 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8112
    Binaries:
      Node: 16.18.1
      npm: 8.19.2
      Yarn: N/A
      pnpm: N/A
    Relevant packages:
      next: 13.0.4-canary.3
      eslint-config-next: 13.0.2
      react: 18.2.0
      react-dom: 18.2.0

What browser are you using? (if relevant)

Chrome 107.0.5304.110 (Official Build) (arm64)

How are you deploying your application? (if relevant)

Vercel (not relevant though)

Describe the Bug

Related to #30876, perhaps a regression.

When using React.useId() from a client component, React throws a hydration error:

'use client'

import { useId } from 'react'

export default function IdCheck() {
  const id = useId()
  return <div id={id}>ID: {id}</div>
}
Error: Hydration failed because the initial UI does not match what was rendered on the server.

See more info here: https://nextjs.org/docs/messages/react-hydration-error

This causes issues in libraries like Headless UI: https://github.com/tailwindlabs/headlessui/issues/1961

Expected Behavior

No error.

Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster

https://codesandbox.io/s/cool-shannon-duxx1w?file=/app/page.tsx

To Reproduce

Note that I couldn't get the Sandbox to run because the app directory requires node 16 and Codesandbox uses node 14.

rijk avatar Nov 17 '22 10:11 rijk

I can reproduce the issue locally.

The issue might be caused by Next.js rendering a different tree between the Server and the Client since the return value of useId is determined by the position of a node in the React tree.

SukkaW avatar Nov 17 '22 11:11 SukkaW

Weirdly, I cannot reproduce this. :eyes: @SukkaW did you use the above reproduction only locally, or have you created a different one? Could you share a link to a GitHub repository? I want to verify this.

balazsorban44 avatar Nov 17 '22 18:11 balazsorban44

It seems to happen when components using useId() are nested. For example, this component triggers the error for me:

"use client";
import { useId } from "react";

const ParentUseId = () => {
  const myId = useId();

  return (
    <div>
      {myId} <ChildUseId />
    </div>
  );
};

const ChildUseId = () => {
  const myId = useId();

  return <>{myId}</>;
};

export default ParentUseId;

I don't have time right now to provide a full repo, but if necessary, I could do this in the weekend :)

stephanvane avatar Nov 18 '22 16:11 stephanvane

I've repro'd, It's a bug in React's StrictMode behavior in Dev. Will fix upstream

gnoff avatar Nov 19 '22 04:11 gnoff

I can replicate this bug on my end as well whilst using HeadlessUI in my repo and also in the examples here. I'm currently using 13.0.6-canary-1.

Edit: the bug also occurs on production, but is minified by React.

mzavattaro avatar Nov 29 '22 01:11 mzavattaro

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Jan 01 '23 12:01 github-actions[bot]