DEV Community

Discussion on: Prevent "window is not defined" Errors With a useClientSide() Custom Hook

Collapse
 
ashconnolly profile image
Ash Connolly

Hi Lars! 👋
Look at this particular bit: joshwcomeau.com/react/the-perils-o...

By rendering something different depending on whether we're within the server-side render or not, we're hacking the system. We're rendering one thing on the server, but then telling React to expect something else on the client.

Somewhat remarkably, React can still handle this situation sometimes. You may have done this yourself, and gotten away with it. But you're playing with fire. The rehydration process is optimized to be ⚡️ fast ⚡️, not to catch and fix mismatches."

That last paragraph helped me understand it.

Sure you're doing something that does achieve the goal and works, but it's something React doesn't expect you to do. React tells you this is wrong by giving you an error that says the client DOM didn't match the server.

If React is giving us an error, we should listen as it could cause serious bugs to pop up in your app, perhaps when React updates or adds some new feature that relies on this error being absent.

Hopefully that helps! 😄👍

Collapse
 
_genjudev profile image
Larson • Edited

Hi Ash,
Thanks for the answer. This helped me a little for now.

what would happen if we don't return null and just use window related stuff in scope?

if (typeof window !== 'undefined') {
    // access window here
  }
Enter fullscreen mode Exit fullscreen mode

I'm not quite sure how hydration is working in detail. I guess that would be clarify a lot for me. Todo for the next days :P

Also an option would be to dynamic import components with client related stuff:

// nextjs - https://nextjs.org/docs/advanced-features/dynamic-import
const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/myComponent'),
  { ssr: false } // disable ssr here
)
Enter fullscreen mode Exit fullscreen mode

That also worked for me pretty well. Im a big fan of abstraction and this clarifies that THIS component should only render on client.