I have a React App and I am trying to use the useState and useEffect hooks to create something like an animation when the user scrolled more than 200px from the top of the page.
This is how my navigation looks like:
And I want to apply width: 0; style property to the image in the middle when the user scrolls down (when he scrolled more than 200px from top), otherwise, when the user scrolls back to the top to "bring it back" on the page with width: 150px;
This is my Navbar component:
import { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import logo from "../assets/images/logo.png";
import "../styles/navbar.scss";
const Navbar = () => {
const [scrollY, setScrollY] = useState(0);
const handleScroll = () => {
const logo = document.querySelector("#logo");
if (window.scrollY > 200) {
logo.style.width = "0";
} else {
logo.style.width = "150px";
}
setScrollY(window.scrollY);
};
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return window.removeEventListener("scroll", handleScroll);
}, [scrollY]);
return (
<header>
<nav>
<Link to="/" className="nav-link">
Grupuri
</Link>
<Link to="/" className="nav-link">
Despre noi
</Link>
<Link to="/" className="nav-link">
Live
</Link>
</nav>
<img src={logo} alt="Maranata Lupeni" id="logo" />
<nav>
<Link to="/" className="nav-link">
Rugaciune
</Link>
<Link to="/" className="nav-link">
Credinta
</Link>
<Link to="/" className="nav-link">
Contact
</Link>
</nav>
</header>
);
};
export default Navbar;
How can I solve this?
You have multiple issues that you need to address for your code to work:
useEffect(() => {). The function would be executed when theuseEffectis called again (dependencies changed) or if the component unmounts. You returned the result of callingremoveEventListener. CallingremoveEventListenerremoved the event listener just after adding it.classNameorstyleproperties.useEffectshould be executed only once. DefinehandleScrollinside theuseEffect, and don't pass any redundant states (likescrollY).scrollY, just if you need to show or hide the element.Example:
Notes: