Hydration error when using <Show> in SolidStart
I am new to SolidStart, I see this talked about in several places but I fail to understand how any of the mentioned solutions applies to my case.
I am trying to conditionally render something using
<Show>
:
This results in a hydration error. I am fairly sure that I understand why I'm getting the error, but what pattern should I use to conditionally render an element like this?9 Replies
That does not solve the issue, unfortunately.
In my case, the resource
user
is preloaded on the route that in turn renders this component, so I assume that when the Footer component function runs, it is already a fulfilled promise.
- Does this mean that deferStream: true
will have no effect here?
- Why, if user()
is fulfilled when this component mounts, is the when
clause in the <Show>
not making the content of the <Show>
not render on mount (and in turn not cause hydration error because the element is there from the get-go)?Hydration errors only happen after SSR, so the preload doesn't come into play.
deferStream: true
prevents the page from streaming until the promise accessed by createAsync
has settled, ensuring that the value is available for rendering.
The fact that the <Show />
isn't rendering suggests that the promise resolved to a falsy value.
One thing you should try is to view to page in incognito as some browser extensions change the DOM which can lead to hydration errors.I tried a fresh browser session, it did not help.
I have been banging my head against this for some time now and can't figure it out, I ended up doing it this way, which works:
If, in the above example, I replace
hasUser()
with user()
in the when
clause, I get the hydration error again.
I would have preferred to put the user()
directly in the when
clause, and I am still wondering if I should have been able to.Can you share the implementation of
getUserQuery
?I got caught up in other things and just got back to this. Giving it another shot ❤️
Are you by any chance passing
<Footer />
as a prop somewhere?
See:
https://discord.com/channels/722131463138705510/1238643925988937820
If so use () => <Footer />
instead.No I believe not, I just use it like this.
Wrapping the
<Show>
in a <Suspense>
seems to fix the issue for me. That led me to adding the suspense tag in the app.tsx file:
And I don't longer need to have the suspense in the footer component. So, I guess I learned that everything async requires a suspense somewhere up the component tree.I guess I learned that everything async requires a suspense somewhere up the component tree.I seem to remember that it was mentioned somewhere that you need supense boundaries for SSR to work if you have async data sources. What wasn't mentioned was how it would fail.