skip to Main Content

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:

https://youtu.be/fdw6WVbqJ30

'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


  1. 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 use useEffect:

    // You'll also want to memoize your `changeColor` function
    // https://react.dev/reference/react/useCallback
    const changeColor = useCallback(() => {
      if (window.scrollY >= 950 || window.location.pathname.includes('/lodge')) {
        setColor(true);
      } else {
        setColor(false);
      }
    }, []);
    
    useEffect(() => {
      // Fire the `changeColor` function once on mount so you don't
      // need to wait for scrolling if any color changes should happen
      // immediately on page load
      changeColor();
    
      // Add the event listener
      window.addEventListener('scroll', changeColor);
    
      return () => {
        // Be sure to clean it up if the component unmounts
        window.removeEventListener('scroll', changeColor);
      };
    }, [changeColor]);
    
    Login or Signup to reply.
  2. you’re calling your changeColor function just on scroll so nothing happens before scroll.you can use this instead :

      useEffect(() => {
         changeColor()
         window.addEventListener("scroll" , changeColor)
    
         return () => {
            window.removeEventListener("scroll" , changeColor)
         }
     }, [])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search