So im pretty new to next js and react. Im trying to make a responsive navbar bar that closes and opens when clicked on the hamburger icon. (It also closes when clicked outside the opened menu).
The issue here is that it does not seem to be closing again after being clicked on the hamburger icon.. despite what i think is the correct logic being applied.
Any ideas whats going on?
import { NAV_LINKS } from "@/constants";
import Image from "next/image";
import Link from "next/link";
import { useState, useEffect, useRef } from "react";
const MobileMenu = () => {
const [active, setActive] = useState(false);
const menuRef = useRef<HTMLUListElement>(null);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (menuRef.current && !(menuRef.current as Node).contains(event.target as Node)) {
setActive(false);
}
};
document.body.addEventListener('click', handleClickOutside);
return () => {
document.body.removeEventListener('click', handleClickOutside);
};
}, []);
const handleToggle = () => {
setActive(prevActive => !prevActive);
};
return (
<div className='lg:hidden'>
{/* Hamburger Icon */}
<div className="cursor-pointer">
<Image
src='/burger-menu.svg'
alt='hamburger menu icon'
width={34}
height={34}
onClick={handleToggle}
className={active ? 'animateBurger' : ''}
/>
</div>
<div className="flex flex-col">
<ul ref={menuRef} className={active ? 'animateMobileMenu' : 'lg:hidden hidden'}>
{NAV_LINKS.map((link) => (
<Link href={link.href} key={link.key}>
{link.label}
</Link>
))}
</ul>
</div>
</div>
)
}
export default MobileMenu
Here is the globals.css code as well being used to animated the icon + menu.
.animateBurger{
@apply transition rotate-90 opacity-25
}
.animateMobileMenu{
@apply transition-all p-24 flex justify-center items-center flex-col z-50 fixed top-20 left-0 w-full gap-12 text-white-10 regular-16 bg-black-100/75 backdrop-blur-sm
}
its because your setActive get set two times when click on Hamburger Icon
try passing ref to nav bar itself
<div className='lg:hidden' ref={menuRef}>
{/* Hamburger Icon */}
<div className="cursor-pointer">
<Image
src='/burger-menu.svg'
alt='hamburger menu icon'
width={34}
height={34}
onClick={handleToggle}
className={active ? 'animateBurger' : ''}
/>
</div>
<div className="flex flex-col">
<ul className={active ? 'animateMobileMenu' : 'lg:hidden hidden'}>
{NAV_LINKS.map((link) => (
<Link href={link.href} key={link.key}>
{link.label}
</Link>
))}
</ul>
</div>
</div>