skip to Main Content

I have a navbar in which there is a button that opens a menu on full screen and in the menu there is a dismiss button. now everything works except the button that opens the menu. It works on double click and not from the first click. it was working until I made the dismiss button

this is the navbar code
NavBar.js

function Navbar() {
  const [openProfile, setOpenProfile] = useState(false);
  const [openMenu, setOpenMenu] = useState(false);



  return (
    <nav className="nav">
      <div className="navbar-menu">
        <button className="float-on-hover" onClick={()=> setOpenMenu(!openMenu)}>
          <FontAwesomeIcon icon={faNavicon} className="fa-2x" />
        </button>
        {openMenu && <Menu /> }
      </div>

      <div className="navbar-user">
        <button className="float-on-hover" onClick={() => setOpenProfile(!openProfile)}>
          {" "}
          <FontAwesomeIcon icon={faUserCircle} className="fa-2x" />
        </button>

        {openProfile && <Dropdown />}
      </div>
    </nav>
  );
}

This is the menu code
Menu.js

function Menu() {
  const [closeMenu, setCloseMenu] = useState(true);

  function dismissButton ()
  {
    setCloseMenu(!closeMenu) 
  }
  return (
 
   <>
    {closeMenu &&
   <div className="menu__page">
      <div className="close__button">
        <button onClick={dismissButton}><FontAwesomeIcon icon={faClose} className="fa-2x" /></button>
      </div>
      
      <div className="menu__content">
        <div className="menu__items">
          <ul>
            <li>
              <a href="#" className="link__item">
                HOME
              </a>
            </li>
            <li>
              {" "}
              <a href="#" className="link__item">
                STANDARD
              </a>
            </li>
            <li>
              <a href="#" className="link__item">
                PREMIUM
              </a>
            </li>
            <li>
              {" "}
              <a href="# " className="link__item">
                LUXURY
              </a>
            </li>
            <li>
              {" "}
              <a href="#" className="link__item">
                WISHLIST
              </a>
            </li>
            <li>
              <a href="#" className="link__item">
                CONTACT
              </a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  }
</>
  );
}

2

Answers


  1. Chosen as BEST ANSWER

    Since the problem was ending up with openMenu=true and closeMenu=true I changed the code as below

    function Navbar() {
      const [openProfile, setOpenProfile] = useState(false);
      const [openMenu, setOpenMenu] = useState(false);
    
    
      return (
        <nav className="nav">
          <div className="navbar-menu">
            <button className="float-on-hover" onClick={()=> setOpenMenu(!openMenu)}>
              <FontAwesomeIcon icon={faNavicon} className="fa-2x" />
            </button>
            {openMenu && <>
       <div className="menu__page">
          <div className="close__button">
            <button onClick={() => setOpenMenu(false)}><FontAwesomeIcon icon={faClose} className="fa-2x" /></button>
          </div>
          
          <div className="menu__content">
            <div className="menu__items">
              <ul>
                <li>
                  <a href="/" className="link__item">
                    HOME
                  </a>
                </li>
                <li>
                  {" "}
                  <a href="/standard" className="link__item">
                    STANDARD
                  </a>
                </li>
                <li>
                  <a href="/premium" className="link__item">
                    PREMIUM
                  </a>
                </li>
                <li>
                  {" "}
                  <a href="/luxury" className="link__item">
                    LUXURY
                  </a>
                </li>
                <li>
                  {" "}
                  <a href="/whishlist" className="link__item">
                    WISHLIST
                  </a>
                </li>
                <li>
                  <a href="/contact" className="link__item">
                    CONTACT
                  </a>
                </li>
              </ul>
            </div>
          </div>
        </div>
    </> }
          </div>
    
          <div className="navbar-user">
            <button className="float-on-hover" onClick={() => setOpenProfile(!openProfile)}>
              {" "}
              <FontAwesomeIcon icon={faUserCircle} className="fa-2x" />
            </button>
    
            {openProfile && <Dropdown />}
          </div>
        </nav>
      );
    }
    

    I included the menu in the navbar and now it works


  2. What it looks like is happening is you have two methods of hiding your menu. One from inside the menu itself, and one from the button to reveal the menu.

    When you click the menu button, and the menu opens, then you click the dismiss menu inside the menu, you end up with openMenu=true and closeMenu=true so the button shows the Menu component, which internally hides itself.

    Then when you click the menu button, it toggles to openMenu=false, which also removes the Menu component (resetting closeMenu).
    Then when you click again, it toggles to openMenu=true again, showing the menu.

    I recommend only having one location where you decide if the menu is visible or not. In this simple case, it’s probably easiest to pass in a "closeMenu" function to the menu itself, which should be called by the Menu component, to edit the navbar’s openMenu variable.

    eg. I’d add:

    const closeMenu = () => {
      setOpenMenu(false);
    }
    

    to the NavBar, then pass this into the Menu component:

            {openMenu && <Menu closeMenu={closeMenu} /> }
    

    Then modify the Menu component to accept it:

    function Menu({closeMenu}) {
      function dismissButton ()
      {
        closeMenu(); 
      }
      return (
       <div className="menu__page">
          <div className="close__button">
            <button onClick={dismissButton}><FontAwesomeIcon icon={faClose} className="fa-2x" /></button>
          </div>
          
          <div className="menu__content">
            <div className="menu__items">
              <ul>
                <li>
                  <a href="#" className="link__item">
                    HOME
                  </a>
                </li>
                <li>
                  {" "}
                  <a href="#" className="link__item">
                    STANDARD
                  </a>
                </li>
                <li>
                  <a href="#" className="link__item">
                    PREMIUM
                  </a>
                </li>
                <li>
                  {" "}
                  <a href="# " className="link__item">
                    LUXURY
                  </a>
                </li>
                <li>
                  {" "}
                  <a href="#" className="link__item">
                    WISHLIST
                  </a>
                </li>
                <li>
                  <a href="#" className="link__item">
                    CONTACT
                  </a>
                </li>
              </ul>
            </div>
          </div>
        </div>
      );
    }
    

    Note: I haven’t run this myself, but the principle is to only ever store the menu’s show/hide variable in one place. If you were using Redux, I’d recommend putting it in the store.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search