Search code examples
javascripthtmlcssreactjshamburger-menu

Converting CSS and HTML hamburger menu into a react component


I am following a tutorial that creates an animated navbar and hamburger manu using css, html and javascript, and I want to create the navbar as a react component for my project.

The code that I am trying to covert is the following, which is an app.js file which is embedded in the html with tags:

const navSlide = () => {
    const burger = document.querySelector('.burger');
    const nav = document.querySelector('.nav-links');

    burger.addEventListener('click', () => {
        nav.classList.toggle('nav-active');
    })
}

navSlide();

I have tried to implement this code into my navbar react component as follows:

import React from "react";

const NavBar = () => {
const nav = document.querySelector(".nav-links");

  return (
    <div className="navbar">
        <nav>
            <ul className="nav-links">
                <li>
                    <a href="#">Menu Item</a>
                </li>
            </ul>
        <div
            className="burger"
            onClick={() => {
                nav.classList.toggle("nav-active");
            }}
        >
          <div className="line1" />
          <div className="line2" />
          <div className="line3" />
        </div>
       </nav>
    </div>
  );
};

export default NavBar;

However this returns the error of: "TypeError: Cannot read property 'classList' of null"

The CSS of .nav-active is as follows:

.nav-active {
  transform: translateX(0%);
}

The result of this I am expecting is for the navbar to toggle open and closed when the burger symbol is clicked


Solution

  • The best option is to go with state. This is should work, have not tested though. ReactJS 16.8 is required for useState hook to work.

    import React, {useState} from "react";
    
    const NavBar = () => {
      const [navOpened, setNavOpened] = useState(false);
      const navClassNames = navOpened ? 'nav-links nav-active' : 'nav-links';
    
      return (
        <div className="navbar">
            <nav>
                <ul className={navClassNames}>
                    <li>
                        <a href="#">Menu Item</a>
                    </li>
                </ul>
            <div
                className="burger"
                onClick={() => setNavOpened(!navOpened)}
            >
              <div className="line1" />
              <div className="line2" />
              <div className="line3" />
            </div>
           </nav>
        </div>
      );
    };