Get scrollbar position with NextJs

I’m using NextJs to take advantage of Server Side Rendering. And also I have a navbar in my application that should change styles with scroll position. How can I check whether the window has been scrolled more than 100px, on my NextJs application?

Answer

You can simply use a useEffect hook like this:

import { useEffect, useState } from "react";

const IndexPage = () => {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      setScrollY(window.scrollY);
    };

    // just trigger this so that the initial state 
    // is updated as soon as the component is mounted
    // related: https://stackoverflow.com/a/63408216
    handleScroll();

    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div style={{ height: 4000 }}> {/* just added to make scrollbar available */}
      <div style={{ position: "fixed", top: 0 }}>
        {scrollY > 100
          ? "Scrolled more than 100px"
          : "Still somewhere near the top!"}
      </div>
    </div>
  );
};

export default IndexPage;

Sandbox: https://codesandbox.io/s/cocky-drake-1xe0g

This code can be further optimized by debouncing the scroll handler. And optionally, setting the state only if it is not changed (not sure if newer versions of React handle this itself).

Your question was directly related to this thread: https://stackoverflow.com/a/59403018/11613622

For debouncing/throttling you can refer this: How to use throttle or debounce with React Hook?

Also if you don’t want to use the provided solutions in that thread simply wrap the handleScroll with _.debounce and then feed it to the event handler.