Next.js Discord

Discord Forum

ScrollY

Unanswered
Brown bear posted this in #help-forum
Open in Discord
Brown bearOP
I’m trying to change the nav bar color when a user scrolls 100 pixels. I'm using the useWindowScroll hook from the "react-use" library, but I'm getting this warning:

Prop `className` did not match. Server: "bg-background" Client: "bg-primary"


I tried to implement my own solution using useState and useEffect to start the color change logic after hydration, but the color change takes a long time to reflect after the page loads.

Here is my current code:

'use client';

import Link from 'next/link';
import { useWindowScroll } from 'react-use';
import { cn } from '@/lib/utils';
import TopbarNav from './Navbar/TopbarNav';
import SidebarNav from './Navbar/SidebarNav';
import Logo from '@/assets/images/svg/logo.svg';

export default function Header() {
  const { y } = useWindowScroll();

  return (
    <header>
      <div
        className={cn(
          'fixed top-0 w-screen z-50 bg-background',
          y > 100 && 'bg-primary'
        )}
      >
        <div className="container max-w-9xl flex justify-between items-center gap-0 p-5 md:px-10 sm:gap-2 md:gap-5">
          <div className="flex gap-5">
            <SidebarNav windowScrollY={y} />
            <Link href="/">
              <Logo
                className={cn(
                  'block w-32 md:w-48 mt-0.5',
                  y > 100 && 'brightness-[1000]'
                )}
              />
              <span className="sr-only">Logo</span>
            </Link>
          </div>
          <TopbarNav windowScrollY={y} />
        </div>
      </div>
    </header>
  );
}


Any advice on how to resolve this issue would be greatly appreciated!

2 Replies

Boston Terrier
This is because, the y value when initially rendered on server is 0 but on client it is probably >100 which is causing the hydration issue.

This video with timestamp from Theo tries to explain hydration issue:

https://youtu.be/PAf6NjyCnrI?si=0lpmPI9kqcRjoWI4&t=388
Nothing comes to mind to solve this particular issues at this point but only the ugly solutions unfortunately.

1) You have to go with your isMounted solution, which is a bit ugly cause you can see the previous state for a while until the page switches to client side rendering.

2) Using supressHydrationWarnings which may or may not work.