Navbar hide and show on Scroll using Custom React Hooks

Navbar hide and show on Scroll using Custom React Hooks

implementing smooth navbar using custom react hooks

Play this article

Making a Custom React Hook

code:

/**
 * useScroll React custom hook
 * Usage:
 *    const { scrollX, scrollY, scrollDirection } = useScroll();
 */

 import { useState, useEffect } from "react";

 export function useScroll() {
    // storing this to get the scroll direction
   const [lastScrollTop, setLastScrollTop] = useState(0);
    // the offset of the document.body
   const [bodyOffset, setBodyOffset] = useState(
     document.body.getBoundingClientRect()
   );
    // the vertical direction
   const [scrollY, setScrollY] = useState(bodyOffset.top);
    // the horizontal direction
   const [scrollX, setScrollX] = useState(bodyOffset.left);
    // scroll direction would be either up or down
   const [scrollDirection, setScrollDirection] = useState();

   const listener = e => {
     setBodyOffset(document.body.getBoundingClientRect());
     setScrollY(-bodyOffset.top);
     setScrollX(bodyOffset.left);
     setScrollDirection(lastScrollTop > -bodyOffset.top ? "down" : "up");
     setLastScrollTop(-bodyOffset.top);
   };

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

   return {
     scrollY,
     scrollX,
     scrollDirection
   };
 }

Styles

I am using css-in-javascript to set the visibility of the nav bar but you can use whatever you like.

const styles = {
    active: {
      visibility: "visible",
      transition: "all 0.5s"
    },
    hidden: {
      visibility: "hidden",
      transition: "all 0.5s",
      transform: "translateY(-100%)"
    }
  }

Finale code would look like this

import React from 'react';

import {useScroll} from './../../hooks/useScroll'

export default function Navbar() {
  const { y, x, scrollDirection } = useScroll();  

  const styles = {
    active: {
      visibility: "visible",
      transition: "all 0.5s"
    },
    hidden: {
      visibility: "hidden",
      transition: "all 0.5s",
      transform: "translateY(-100%)"
    }
  }

    return (
        <nav className="Header" style={scrollDirection === "down" ? styles.active: styles.hidden}   >
        <Link to="/" className="Header__link">
            <img src={Logo} height="50px" width="auto" alt="logo"/>
            <div className="Header__link__title">
              Chronology
            </div>
        </Link>  
        <ul className="flex">
            <li>
              <Link to="/about" className="Header__link">About</Link>
            </li>
            <li>
              <Link to="/blog" className="Header__link">Blogs</Link>
            </li>
          </ul>
        </nav>       
    )
}

I know this is very lazy writing but it's already midnight.

I will write in detail about it.

I hope it help someone.

Did you find this article valuable?

Support Pratik Sharma by becoming a sponsor. Any amount is appreciated!