This NextJS code changes the color of the Navbar elements after 950 px below and if the Navbar appears on a separate page, however, when switching to another page there is a delay in changing the Navbar colors until I start scrolling.
Here’s a video demonstrating this:
'use client'
import Image from "next/image"
import Link from "next/link"
import Container from "../Container"
import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
const Navbar = () => {
const [color, setColor] = useState(false)
const changeColor = useCallback(() => {
if (window.scrollY >= 950 || window.location.pathname.includes('/lodge')) {
setColor(true);
} else {
setColor(false);
}
}, []);
useEffect(() => {
changeColor();
window.addEventListener('scroll', changeColor);
return () => {
window.removeEventListener('scroll', changeColor);
};
}, []);
const [image, setImage] = useState(false)
const changeImage = useCallback(() => {
if (window.scrollY >= 950 || window.location.pathname.includes('/lodge')) {
setImage(true);
} else {
setImage(false);
}
}, []);
useEffect(() => {
changeImage();
window.addEventListener('scroll', changeImage);
return () => {
window.removeEventListener('scroll', changeImage);
};
}, []);
return (
<div className="fixed w-full backdrop-blur-sm shadow-sm">
<div className="py-4 border-b-[2px]">
<Container>
<div className="flex flex-row items-center justify-between gap-4">
<Link href="/">
{image ? (
<Image className="" src="/images/logo-b.svg" alt="logo-b" width={132} height={58}/>
) : (
<Image className="" src="/images/logo.svg" alt="logo" width={132} height={58}/>
)}
</Link>
<div className="text-2xl text-white font-medium xl:pl-[632px] md:block hidden">
<Link
href="/lodge"
className={color ? 'text-[#313131]' : 'text-white'}
>
LODGE
</Link>
</div>
<div className="text-2xl text-white font-medium md:block hidden">
<div className={color ? 'text-[#313131]' : 'text-white'}>
<Link href="/blog">
OUR BLOG
</Link>
</div>
</div>
<div className="text-white text-2xl font-medium flex flex-row items-center gap-3">
<div className="relative sm:w-5 sm:h-5 md:w-5 md:h-5">
{image ? (
<Image src="/images/tel-b.svg" alt="tel" width={24} height={24}/>
) : (
<Image src="/images/tel.svg" alt="tel-b" width={24} height={24}/>
)}
</div>
<div className="">
<div className={color ? 'text-[#313131]' : 'text-white'}>
NUM
</div>
</div>
</div>
<div className="text-2xl text-white font-medium flex flex-row items-center gap-3">
<div className={color ? 'text-[#313131]' : 'text-white'}>
<div className="sm:block cursor-pointer">
EN
</div>
</div>
<div className={color ? 'text-[#313131]' : 'text-white'}>
|
</div>
<div className={color ? 'text-[#313131]' : 'text-white'}>
<div className="sm:block cursor-pointer">
ES
</div>
</div>
</div>
</div>
</Container>
</div>
</div>
)
}
export default Navbar;
Still haven’t solved the problem
2
Answers
So, you currently attach the event listener with
window.addEventListener('scroll', changeColor)
. This has a problems you’re doing this on every render and it scenarios where the component isn’t actually mounted to the window yet (e.g. server rendering). This is also how you can control your desired behavior. You want to useuseEffect
:you’re calling your changeColor function just on scroll so nothing happens before scroll.you can use this instead :