Warning: Prop `className` did not match. Server: ".." and Hydration
Unanswered
Daggertooth pike conger posted this in #help-forum
Daggertooth pike congerOP
Hello!
Been using Next 13 for a couple of months now and mostly got the hang of it except for one thing.
I quiet don´t get the Hydration errors in my client component.
I might be stupid for that question, but isn´t one of the reasons for using client components, that you can conditionally render your DOM? I dont even want the server to render anything if it is marked as a client component...
Why do I have (according to nextjs itself) to use stuff like this:
to conditionally render my components?
Also I just got this error for the first time Warning: Prop
Server: "w-full p-3 border border-purple/60 flex justify-between items-center rounded-l-xl"
Client: "w-full p-3 border border-purple/60 flex justify-between items-center rounded-xl bg-purple/10"
I mean this conditional class rendering is one of the reasons i marked my component as "use client"...
Can someone give me some explanation on why this is "bad practise"? And also is there a better way to fix this, except for this
Thanks a lot in advance!
Been using Next 13 for a couple of months now and mostly got the hang of it except for one thing.
I quiet don´t get the Hydration errors in my client component.
I might be stupid for that question, but isn´t one of the reasons for using client components, that you can conditionally render your DOM? I dont even want the server to render anything if it is marked as a client component...
Why do I have (according to nextjs itself) to use stuff like this:
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])to conditionally render my components?
Also I just got this error for the first time Warning: Prop
className did not match. Server: "w-full p-3 border border-purple/60 flex justify-between items-center rounded-l-xl"
Client: "w-full p-3 border border-purple/60 flex justify-between items-center rounded-xl bg-purple/10"
I mean this conditional class rendering is one of the reasons i marked my component as "use client"...
Can someone give me some explanation on why this is "bad practise"? And also is there a better way to fix this, except for this
const [isClient, setIsClient] = useState(false) ? Thanks a lot in advance!
21 Replies
You need to make sure that what gets rendered initially on the client component matches exactly what the server renders, then rerender your client component to your desired styles. You can do this using a use effect hook with an empty dependency array, as any code in this will only run once, and only on the client.
@フェイン (Fane) You need to make sure that what gets rendered initially on the client component matches exactly what the server renders, then rerender your client component to your desired styles. You can do this using a use effect hook with an empty dependency array, as any code in this will only run once, and only on the client.
Daggertooth pike congerOP
Hmm, yeah I get that, this is what I meant by using this code:
but I dont understand why next bothers to render a client component at all on the server side?
Isnt the point of a client component, that it gets rendered on the client side?
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
return <div>{isClient && ...}</div>but I dont understand why next bothers to render a client component at all on the server side?
Isnt the point of a client component, that it gets rendered on the client side?
The useEffect hook with the useState feels so "unclean" if you know what i mean...
And what is the problem in general with having missmatching DOMs on the server and client side in client components?
That is how you get benefits of Ssr. Seo optimization, performance, etc. everything gets rendered on the server, and sent to client as html, waiting to be hydrated if necessary.
The server expects a specific dom for hydration, if it is off, it can try to force it, but things can and will go wrong. Which is why you see the warning
Yeah I don’t like the pattern of the usestate to determine if it’s client either. I haven’t encountered that myself
Daggertooth pike congerOP
Ok I see. Well I guess in that case I do have to use this workaround with useEffect with empty braces 😄
Thanks!
Thanks!
Let me know how it goes! Still new to this so it’s interesting to see this come up for styles
Daggertooth pike congerOP
Have had it like 4-5 times now in my app, although sometimes I do seem to be able to conditionally render on client side without the workaround, but whatever... IT is a black box i guess haha
Those questions are very common, I've crafted a course around this topic and managing client-only code in React more broadly: https://course.nextjspatterns.com/manage-client-only-code-in-next-js-with-react-browser-components
This is not technically Next specific, according to Dan Abramov React has always been designed with server-side rendering "compatibility" in mind
eventhough only recent frameworks like Next.js can actually make it possible by providing the backend requirements for that
If "useClient" is inconvenient, a NoSsr wrapper could do the trick too
you apply it from the parent, so the child doesn't have to bother with the "useClient" hook
<NoSsr><FoobarClient /></NoSsr>
this is not a super good practice but it's acceptable to build "unfriendly" React component (in my opinion) if you really have strong client needs
like you are building stuff with webgl etc. that will never ever make sense in a prerendered app
an extreme scenario is using eg leaflet or jquery = > they will even crash the server so you also need "next/dynamic" to make them work
Ah found the tweet finally: https://twitter.com/ericbureltech/status/1707729362777231814
@Eric Burel Those questions are very common, I've crafted a course around this topic and managing client-only code in React more broadly: https://course.nextjspatterns.com/manage-client-only-code-in-next-js-with-react-browser-components
Daggertooth pike congerOP
Aaah thats interesting! I will definetly have a look at this. Thank you very much!