I am getting state= false on desktop size when there is no toggle option as it is defined as false initially. Because of this, no menus are showing. I want this functionality only when the website is opened on mobile, not on desktop.
const Navbar = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const toggle = () => setIsMenuOpen(!isMenuOpen);
const ref = useRef();
useEffect(() => {
const checkIfClickedOutside = (e) => {
if (!ref.current?.contains(e.target)) {
setIsMenuOpen(false);
}
};
document.addEventListener("mousedown", checkIfClickedOutside);
return () => {
document.removeEventListener("mousedown", checkIfClickedOutside);
};
}, []);
return (
<>
<header>
<nav>
<div className="nav">
<div className="nav-brand">
<Link to="./" className="text-black">
Website
</Link>
</div>
<div ref={ref}> // <-- ref to this containing div
<div className="toggle-icon" onClick={toggle}>
<i
id="toggle-button"
className={isMenuOpen ? "fas fa-times" : "fas fa-bars"}
/>
</div>
{isMenuOpen && (
<div className={isMenuOpen ? "nav-menu visible" : "nav-menu"}>
....
</div>
)}
</div>
</div>
</nav>
</header>
</>
);
};
Create an initial state value that checks if the window's width is greater than your mobile media query size.
* Small devices (landscape phones, less than 768px) */
@media only screen and (max-width: 767.98px) {
/* -------------Bottom Header------------- */
.....
}
Example:
const isMobile = window.innerWidth <= 767.98;
export default function App() {
const [isMenuOpen, setIsMenuOpen] = useState(!isMobile);
const toggle = () => isMobile && setIsMenuOpen(!isMenuOpen);
const ref = useRef();
useEffect(() => {
if (isMobile) {
const checkIfClickedOutside = (e) => {
if (!ref.current?.contains(e.target)) {
setIsMenuOpen(false);
}
};
document.addEventListener("mousedown", checkIfClickedOutside);
return () => {
// Cleanup the event listener
document.removeEventListener("mousedown", checkIfClickedOutside);
};
}
}, []);
return ( .... );
}
This, OFC, assumes that the app's viewport is static. If you need a dynamic response then use an useEffect hook to add an onResize event handler to the window object.
Example:
useEffect(() => {
const resizeHandler = () => {
... logic to get window size and handle setting the menu state
};
window.addEventListener("resize", resizeHandler);
return () => {
window.removeEventListener("resize", resizeHandler);
};
}, []);