Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

hamburger toogle button not working react

import React, { useState, useEffect, useRef } from "react";
import { Link } from "react-router-dom";
import "./index.css";


const Navbar = () => {

    const [isMenuOpen, setIsMenuOpen] = useState(false);
    const toggle = () => setIsMenuOpen(!isMenuOpen);
    const ref = useRef()
    useEffect(() => {
        const checkIfClickedOutside = e => {
          if (isMenuOpen && ref.current && !ref.current.contains(e.target)) {
            setIsMenuOpen(false)
          }
        }
        document.addEventListener("mousedown", checkIfClickedOutside)
        return () => {
          document.removeEventListener("mousedown", checkIfClickedOutside)
        }
      }, [isMenuOpen])

    return (
        <>
            <header>

                <nav>
                    <div className="nav">

                        <div className="nav-brand">
                            <Link to="./" className="text-black">Website</Link>
                        </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"} ref={ref}>
                                <ul className="main-menu">

                                    <li><Link to="./" onClick={toggle}>Home</Link></li>
                                    <li><Link to="./blog" onClick={toggle}>Blog</Link></li>
                                    <li className="drp">
                                        <p className="dropbtn">Find <i className="fa-solid fa-angle-down"></i></p>
                                        <ul className="dropdown-content">
                                            <li><Link to="./find/portable-keyboards" onClick={toggle}>Portable Keyboards</Link></li>
                                        </ul>
                                    </li>
                                    <li className="drp">
                                        <p className="dropbtn">More <i className="fa-solid fa-angle-down"></i></p>
                                        <ul className="dropdown-content">
                                            <li><Link to="./piano-notes" onClick={toggle}>Piano Notes</Link></li>
                                            <li><Link to="./chords" onClick={toggle}>Chords</Link></li>
                                            <li><Link to="./tools/metronome" onClick={toggle}>Metronome</Link></li>
                                        </ul>
                                    </li>
                                </ul>
                            </div>
                        )}
                    </div>
                </nav>  
            </header>

        </>
    )
}

export default Navbar;

Everything is working fine except the toggle button. The menu is not closing after opening it. The onClick={toggle} function is not working on the close icon. The menu will hide when someone clicks outside the menu component which is working fine. I tried a lot but didn’t find any method to resolve it. Can someone try to solve this issue?

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Issue

The menu toggle button is outside the element you are attaching the outside click listener to, so when you are trying to close the menu the toggle callback and the checkIfClickedOutside handlers are cycling the isMenuOpen state.

Solution

Wrap both the menu button and the menu in a div for the ref to be attached to. There is also no reason really to check if isMenuOpen is true in the checkIfClickedOutside handler. If isMenuOpen is already false, enqueueing another state update to set it false is generally ignored by React. This allows you to remove it as a dependency.

Example:

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>
    </>
  );
};

Edit hamburger-toogle-button-not-working-react

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading