-
Notifications
You must be signed in to change notification settings - Fork 47.5k
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 18 requests similar component trees for the useId #22733
Comments
Just to set expectations -- We're heads down preparing for the conf so the response may be delayed but thanks for a good writeup. |
Which conf is that one @gaearon? |
|
I think I'm running into the same thing here. On the server side, I need to wrap my app with a shell like this: <html>
<body>
<div id="root"></div> <!-- this is what gets hydrated on the client side -->
</body>
</html> This works great until I start using Is this considered a bug or expected behavior? Is there a better workaround that I'm just not aware of? |
|
Thanks for the confirmation @theKashey. Looking at the SSR demo it seems like the expected pattern is to hydrate the entire document on the client side and not just the app root. I haven't tried this myself, but maybe it could work? react/fixtures/ssr2/src/index.js Line 12 in 1780659
That said, it looks like they are wrapping the app root in a data provider on the server only: react/fixtures/ssr2/server/render.js Lines 41 to 43 in 1780659
So, I'm guessing they will have hydration mismatch errors if anything in |
It's actually pretty simple thing - Let's assume we have <App/>
// is the same as
<Provider>
<AnotherProvider>
<App/>
</AnotherProvider>
</Provider> because there is no "difference in sibling" in parents. And the change in parents does not matter. Given another example <>
<Stuff/>
<App/>
</>
// is the same as
<>
<Stuff>
<SomeOtherStuff/>
</Stuff>
<App/>
</> Because there is change, but not among "siblings in parents" - change is in "another tree branch", which will have issues using |
I'd say that's a mistake in the example.
The canonical solutions are either to add this wrapper to the client (and hydrate the whole document) or not use React to generate this wrapper on the server either. |
@theKashey thanks for the clarification. I didn't realize that it had to do with the siblings. @gaearon thanks for information on the suggested solutions. I'll have to rethink quite a bit about how I approach SSR, but at least now I know what I should be aiming for. |
Ah - this is exactly what I was battling yesterday! I think this thread explains the behavior I was seeing and maybe there's room for a small docs update or clarity. I was confused by what I read in the docs versus the behavior I was seeing. The current docs don't mention how
If it really does come down to both the parents and their siblings then I would suggest updating the docs to be a bit clearer. It currently reads to me like only the path to the current component matters, not the siblings along that path. Here's a simplified example showing the parent sibling impact on |
Origins
Historically SSR was requiring some extra components to create a special "server" environment. Usually the ServerApplication is expected to be wrapped with different
collectors
andproviders
in order to power code splitting, style extraction, media queries, and many other things, some part of which don't have to be used on the client side, or even cannot exists at all.ClientSide in turn, might contain some elements not required for the Server
The problem
According to my experiments for the proper use of
useId
one does not need ideally matching component trees - any number of "wrappers" are allowed, and only having "more than one child" is breaking id generation, however it does not cause any hydration id and cannot be detected without a context-aware test.The question
What level of similarity is really required? What actually matters - the path(so internals of siblings do not matter), or everything "before this point"(probably not due to Selective Hydration)?
How one can understand are component trees are similar enough, or one should not try to do that, comparing the expected behavior (matching Ids) without relying on implementation details of
useId
(currently one has to)The text was updated successfully, but these errors were encountered: