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?
Asked
Active
Viewed 1.5k times
1 Answers
9
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.

brc-dd
- 10,788
- 3
- 47
- 67
-
I'm using ServerSide rendering here and I suspect that's why I"m not seeing the output. Could you try adding SSR to the page and see if this work please? It didn't work for me – Sachin Titus Jun 22 '21 at 18:07
-
1@SachinTitus It is working on SSR also, I have updated the sandbox to export `getServerSideProps` which will make Next.js server render that page. – brc-dd Jun 22 '21 at 18:17
-
Do you expect this code snippet ot work on any of the higher order components and other components as well? I have a Layout Component which is an HOC i use inside the page – Sachin Titus Jun 22 '21 at 18:20
-
if I wrap the page content with Layout hoc, it doesn't seem to work. but if there's no HOC around the code inside return statement, it works – Sachin Titus Jun 22 '21 at 18:23
-
@SachinTitus Technically wrapping your component in some HOC should not effect this functionality. Can you show the relevant code that your Layout HOC is putting? Also, I didn't quite understand what you meant by _"other components"_. The state will be accessible inside whatever component you define it. – brc-dd Jun 22 '21 at 18:28
-
I'll create a code sandbox and share it with you. Thank you for helping mind – Sachin Titus Jun 22 '21 at 18:34
-
Got the solution. It's the overflow-x:hidden in my code which causes the issue. Thanks for the help – Sachin Titus Jun 23 '21 at 05:10