Smooth Navbar hide and show on Scroll using Custom React Hooks

Pratik Sharma
2 min readJul 4, 2021

--

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.

--

--