-
Notifications
You must be signed in to change notification settings - Fork 27.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React.useId() usage results in hydration mismatch #43033
Comments
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 |
Weirdly, I cannot reproduce this. 👀 @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. |
It seems to happen when components using "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 :) |
I've repro'd, It's a bug in React's StrictMode behavior in Dev. Will fix upstream |
In `<StrictMode>` in dev hooks are run twice on each render. For `useId` the re-render pass uses the `updateId` implementation rather than `mountId`. In the update path we don't increment the local id counter. This causes the render to look like no id was used which changes the tree context and leads to a different set of IDs being generated for subsequent calls to `useId` in the subtree. This was discovered here: vercel/next.js#43033 It was causing a hydration error because the ID generation no longer matched between server and client. When strict mode is off this does not happen because the hooks are only run once during hydration and it properly sees that the component did generate an ID. The fix is to not reset the localIdCounter in `renderWithHooksAgain`. It gets reset anyway once the `renderWithHooks` is complete and since we do not re-mount the ID in the `...Again` pass we should retain the state from the initial pass.
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. |
Fixes #43033 Also remove the unsued react-dom files: bundles for bun, and react-dom-test-utils x-ref: facebook/react#25713 ## Bug - [x] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
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. |
Verify canary release
Provide environment information
next info:
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:This causes issues in libraries like Headless UI: tailwindlabs/headlessui#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.
The text was updated successfully, but these errors were encountered: