- read

Stop using scroll event like this in Next.js

Șener Ali 100

scroll event next js 13
Scroll Event Next.js 13

Picture this: you’re crafting a dynamic website, and naturally, you’re incorporating the much-needed scroll event. But here’s the catch — if you don’t use the scroll event listener strategically, brace yourself for an onslaught of component rerenders. After all, who wants their meticulously crafted components to reload needlessly as users casually traverse the page?

Let’s write some code to understand better the problem and try to solve it.

Step 1: Setting the Stage

Let’s establish our foundation. Here’s a glimpse of the initial folder structure:

.
├── src
│ ├── app
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ ├── page.module.css
│ │ ├── page.tsx
│ └── hooks
│ └── useScroll.ts
└── [..]

Step 2: Introducing useScroll

Here is the useScroll hook, that has a scrollPosition state variable that gets updated when the window is scrolling.

import { useState, useEffect } from "react";

interface ScrollPosition {
x: number;
y: number;
}

const useScroll = (): ScrollPosition => {
const [scrollPosition, setScrollPosition] = useState<ScrollPosition>({
x: 0,
y: 0,
});

const handleScroll = () => {
setScrollPosition({
x: window.scrollX,
y: window.scrollY,
});
};

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

return scrollPosition;
};

export default useScroll;

Step 3: Styling

Before building the page.tsx file, we will add some basic styles in the page.module.css.

.header {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100vw;
padding: 2.5rem 6.25rem;
background-color: red;
}

.header.active {
background-color: blue;
}

.navList {
display: flex;
align-items: center;
column-gap: 1.5rem;
}

.navItem {
color: white;
}

Also, in the globals.css file, you should use the following styles.

* {
box-sizing: border-box…