-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
useId not stable after upgrade to Remix 2.4.1 (from 2.1) introduced with fetcher key feature. #8393
Comments
Ok, the monorepo is a red herring. It happens as soon as I do useId in a separate component. |
I’m 99% sure this is the issue, you’re most likely using two copies of React. |
That was my original guess too, so I put a console.log inside the useId function in React in node_modules, and the singular console.log call logged both the stables and unstable useIds on both the client and server, leading me to be fairly confident there's only one copy (I also checked with pnpm why) and went through my package lock, just in case). There's really only one copy. I was also able to eventually repro without the monorepo setup. I unfortunately CANNOT repro in a simple app created from the Remix template, so there's more to it unfortunately. |
Ok, I was able to do a minimal repro. It seems to only happen when a file has useFetcher, useId, and imports another component using useId. Reproduced with a default Remix template and only the changes above: https://github.com/Phoenixmatrix/remix-unstable-useid |
Ok, narrowed it down to a bug with the new fetcher key implementation, though I don't fully understand what's happening. The default fetcher key generation will behave fairly differently server side than client side. Server side the module might be a singleton (eg: in Express) while on the client side it would start over with every request. If you actually set a key on the fetcher, the hydration mismatch no longer happen with useId, because it's now stable. Maybe because useId is interlinked with useState in some ways? The issue happens even if you don't do anything with the fetcher (just calling useFetcher causes the problem, and call it with a key resolves it. Even if the dom is exactly the same minus useId) My assumption is that if the default fetcher key used |
Ok, final update for tonight. I'm wondering if the default fetcher key shouldn't just use If in my code I do the following, then everything works: const key = useId();
const fetcher = useFetcher({key)); Which essentially replaces the internal singleton key generator with useId without needing to hardcode a key. No more hydration fetcher. Using this workaround for now until there's a better fix. |
Wow. Awesome bit of detective work. I'm glad you were able to find a workaround for now. I'm sure the team will resolve this. |
I run into the same issue, as soon as you bring a dependency that manage id with Some additional context :
Here a Stackblitz |
Thanks for the deep dive! I'll take a look into this.
Unfortunately it's not this simple because React Router still supports React 17. I will see if feature detection is a possibility though. |
Oh boy yeah. I didn't do SSR when I was on React 17, so I never thought about how to generate stable IDs dynamically like this without |
This is resolved by remix-run/react-router#11166 and will be available in the next release |
Reproduction
https://github.com/Phoenixmatrix/remix-unstable-useid
Repro steps if not using the above repo:
useId
anduseFetcher
useId
System Info
Used Package Manager
pnpm
Expected Behavior
Stable useId, like in Remix 2.1
Actual Behavior
useId isn't stable in files using
useFetcher
and components that useuseId
The text was updated successfully, but these errors were encountered: