Home > Enterprise >  Hamburger menu in react
Hamburger menu in react

Time:03-28

I have a hamburger menu in javascript that I'm trying to recreate in React.

Hamburger Menu in Javascript:

function hamburgerMenu() {

  const menuIcon = document.querySelector('.hamburger-menu');
  const mainNav = document.querySelector('.header-links-container');
  const hamLinks = document.querySelectorAll('.header-links a');

    //hamburger function
    function hamburger (){
        menuIcon.classList.toggle('change');
        mainNav.classList.toggle('change');
    }

    //when click on hamburger menu
    menuIcon.addEventListener('click', () => {
        hamburger();
    });

    //when click on links, hamburger menu closes
    for(var i =0 ; i<hamLinks.length;i  ){
      hamLinks[i].addEventListener('click',()=>{
          hamburger();
      });
    }
}   
    hamburgerMenu();

Below I have tried to implement it in React but with this, it seems like it adds the class of .change but the hamburger menu doesn't open.

const Header = () => {
  const [isActive, setActive] = useState(false);

  const openHam = () => {
    const toggleClass = () => {
      setActive(!isActive);
    };

    toggleClass();
  };

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

  return (
    <div className={`header-links-container ${isActive ? 'change' : null}`} onClick={openHam}>
      <div className={`hamburger-menu ${isActive ? 'change' : null}`} onClick={openHam}>
          <div className="line line-1"></div>
          <div className="line line-2"></div>
          <div className="line line-3"></div>
      </div>
      <div className="header-links">
          <a href="/" onClick={closeMenu}>Luxury Suites</a>
          <a href="/" onClick={closeMenu}>Exclusive Clubs</a>
          <a href="/" onClick={closeMenu}>Contact Us</a>
      </div>
    </div>
  );
};

export default Header;

CSS:

.header-links-container {
  width: 200px;
  height: 100%;
  background-color: #2b2b2b;
  position: fixed;
  top: 0;
  right: -300px;
  display: flex;
  justify-content: center;
  align-items: center;
  transition:  right .8s cubic-bezier(1, 0, 0, 1);
  z-index: 4;

  & .hamburger-menu {
  width: 35px;
  height: 30px;
  position: fixed;
  top: 10px;
  right: 10px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: space-around;

  & .line {
      width: 80%;
      height: 3px;
      background-color: $yellow;
      transition: all 0.8s;
      font-size: 1.17em;
  }

  & .change {
      & .line-1 {
          transform: rotateZ(-405deg) translate(-8px, 6px);
          background-color: #fff;
      }
      & .line-2 {
          opacity: 0;
      }
      & .line-3 {
          transform: rotateZ(405deg) translate(-8px, -6px);
          background-color: #fff;
      }
  }
}

& .header-links {
  display: flex;
  flex-direction: column;
}

 & .change {
   right: 0;
  }
}

Please any help would be appreciated.

CodePudding user response:

You are using scss nesting in the wrong way. The "change" should be separated from "header-links-container".

Or you can use a more understandable class name like "header-links-container-active". Then nest it like "&-active" in "header-links-container".

Try this:

SCSS:

.header-links-container {
  width: 100px;
  height: 100%;
  background-color: #eee;
  position: fixed;
  top: 0;
  right: 0;
  opacity: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 4;
  transition: all 0.5s;

  .header-links {
    display: flex;
    flex-direction: column;
  }
}
.change {
  opacity: 1;
  width: 200px;
}

.hamburger {
  position: fixed;
  height: 3rem;
  width: 3rem;
  top: 1rem;
  right: 1rem;
  cursor: pointer;
  text-align: center;
  z-index: 100;

  &__icon {
    position: relative;
    margin-top: 1.5rem;

    &,
    &::before,
    &::after {
      width: 2rem;
      height: 2px;
      background-color: #333;
      display: inline-block;
    }

    &::before,
    &::after {
      content: "";
      position: absolute;
      left: 0;
      transition: all 0.2s;
    }

    &::before {
      top: -0.8rem;
    }
    &::after {
      top: 0.8rem;
    }
  }

  &-active &__icon {
    background-color: transparent;
  }

  &-active &__icon::before {
    top: 0;
    transform: rotate(135deg);
  }

  &-active &__icon::after {
    top: 0;
    transform: rotate(-135deg);
  }
}

JS:

const Hamburger = () => {
  const [isActive, setActive] = useState(false);

  const openHam = () => {
    const toggleClass = () => {
      setActive(!isActive);
    };

    toggleClass();
  };

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

  return (
    <>
      <div
        className={`hamburger ${isActive ? "hamburger-active" : ""}`}
        onClick={openHam}
      >
        <span >&nbsp;</span>
      </div>
      <div className={`header-links-container ${isActive ? "change" : ""}`}>
        <div className="header-links">
          <a href="/" onClick={closeMenu}>
            Luxury Suites
          </a>
          <a href="/" onClick={closeMenu}>
            Exclusive Clubs
          </a>
          <a href="/" onClick={closeMenu}>
            Contact Us
          </a>
        </div>
      </div>
    </>
  );
};

export default Hamburger;
  • Related