skip to Main Content

I have created a changeColour function where the navbar changes colour after scrolling beyond a certain point which works perfectly. The problem is I only want it to take effect on my Home page and every other page (AboutUs, Shop, ContactUs) continues with my .navbarbg .nav-list-green a .nav-list-green a:hover selectors.

Here is my code so far:

Navbar.jsx

'use client'

import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import Logo from './Logo.jsx'
import '../App.css'

const Navbar = () => {
    const state = useState()

    const navigation = [ 
      {_id:101, title: 'ABOUT US', href: '/AboutUs'},
      {_id:102, title: 'SHOP', href: '/Shop'},
      {_id:103, title: 'MENU', href: '/Menu'},
      {_id:104, title: 'CONTACT US', href: '/ContactUs'},
    ];
    
    const [colour, setColour] = useState(false)

    useEffect(() => {
      const changeColour = () => {
        setColour(window.scrollY >= 650)
      };

      window.addEventListener('scroll', changeColour);

      return () => {
        window.removeEventListener('scroll', changeColour)
      }
    }, [])
    

  return (
    <div className={colour ? 'navbar navbarbg' : 'navbar'}>
      <div className="container">
        <Logo />
        <ul className={colour ? 'nav-list-beige nav-list-green' : 'nav-list-beige'}
          >
          {
            navigation.map((item) => (
              <Link to={item?.href} key={item._id}>
                <li className={colour ? 'nav-link nav-link-colour' : 'nav-link'}>
                  {item?.title}
                  <span className={`${item?.href === state && 'style=color: blue;'}`}></span>
                </li>
              </Link>
            ))
          }
        </ul>
        <div>
          
        </div>
      </div>
    </div>
  )
}

export default Navbar

My App.css

/* navbar.jsx CSS */
.navbarbg {
  background-color: hsl(0, 0%, 100%);
  backdrop-filter: blur(30px); 
  box-shadow: 1px 1px 5px 1px hsl(0, 0%, 63%);
  transition-duration: 500ms;
}

.navbar {
  /* (green) background-color: hsl(96, 24%, 44%, 90%); */
  /* background-color: hsl(49, 87%, 88%); */
  /* border-bottom: 1px solid black; */
  position: fixed; top: 0px;
  height: 80px;
  width: 100%;
  z-index:99;
  transition-duration: 500ms
}

.nav-list-beige {
  display: flex;
  gap: 50px;
  list-style-type: none;
  justify-content: center;
  font-size: larger;
  display: flex;
  position: relative; top: -30px; left: 350px;
}

.nav-list-beige a {
  color: hsl(48, 54%, 89%);
  text-decoration: none;
  transition-duration: 500ms;
}

.nav-list-beige a:hover {
  color: hsl(48, 100%, 85%);
  transition-duration: 300ms;
  text-shadow: 0px 0px 2px;
}

.nav-list-green a {
  color: hsl(0, 0%, 0%);
}

.nav-list-green a:hover {
  color: hsl(96, 24%, 44%);
}

Any suggestions will be much appreciated please?

2

Answers


  1. At the

          const changeColour = () => {
            setColour(window.scrollY >= 650)
          };
    

    part, you could have a conditional, like

          const changeColour = () => {
            if (isItHomePage()) setColour(window.scrollY >= 650)
          };
    

    and then you will need to implement isItHomePage like

    function isItHomePage() {
        return window.location.href.indexOf("<your home url>") === 0;
    }
    
    Login or Signup to reply.
  2. Use the useLocation hook to access the current pathname value and the matchPath utility to test if the current pathname matches a specific path, e.g. like a "home page" on "/". The pathname should be used as a dependency in the useEffect hook to re-enclose the current pathname value in the changeColor handler when instantiating the scroll event listeners.

    Basic Example:

    import React, { useState, useEffect } from "react";
    import { Link, matchPath, useLocation } from "react-router-dom";
    
    ...
    
    const { pathname } = useLocation();
    
    useEffect(() => {
      const changeColour = () => {
        const isHome = matchPath("/", pathname);
    
        setColour(isHome && window.scrollY >= 650);
      };
    
      // invoke once to check in case page is already scrolled down when rendering
      changeColour();
      window.addEventListener("scroll", changeColour);
    
      return () => {
        window.removeEventListener("scroll", changeColour);
      };
    }, [pathname]);
    
    ...
    

    Full code:

    import React, { useState, useEffect } from "react";
    import { Link, matchPath, useLocation } from "react-router-dom";
    
    const navigation = [
      { _id: 100, title: "HOME", href: "/" },
      { _id: 101, title: "ABOUT US", href: "/AboutUs" },
      { _id: 102, title: "SHOP", href: "/Shop" },
      { _id: 103, title: "MENU", href: "/Menu" },
      { _id: 104, title: "CONTACT US", href: "/ContactUs" }
    ];
    
    const Navbar = () => {
      const { pathname } = useLocation();
    
      const state = useState();
      const [colour, setColour] = useState(false);
    
      useEffect(() => {
        const changeColour = () => {
          const isHome = matchPath("/", pathname);
    
          setColour(isHome && window.scrollY >= 650);
        };
    
        changeColour();
        window.addEventListener("scroll", changeColour);
    
        return () => {
          window.removeEventListener("scroll", changeColour);
        };
      }, [pathname]);
    
      return (
        <div className={colour ? "navbar navbarbg" : "navbar"}>
          <div className="container">
            <Logo />
            <ul
              className={
                colour ? "nav-list-beige nav-list-green" : "nav-list-beige"
              }
            >
              {navigation.map((item) => (
                <Link to={item?.href} key={item._id}>
                  <li className={colour ? "nav-link nav-link-colour" : "nav-link"}>
                    {item?.title}
                    <span
                      className={`${item?.href === state && "style=color: blue;"}`}
                    ></span>
                  </li>
                </Link>
              ))}
            </ul>
            <div></div>
          </div>
        </div>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search