reactjsreact-navigationresponsivehamburger-menu

React beginner. My NavBar gives error of "Uncaught TypeError: Cannot read properties of null (reading 'addEventListener') i cant seem to tell why."


I try to create and use an animated hamburger menu icon instead of already made icons for my Navbar component



`const menu = document.querySelector('.menu_button');
  const showMenu = document.querySelector('.mobile-nav');
  let menuOpen = false;

  console.log(menu);
  
  menu.addEventListener('click', () => {
      if(!menuOpen){
          menu.classList.add('close');
          showMenu.classList.add('open');
          menuOpen= true;
      } else {
          menu.classList.remove('close');
          showMenu.classList.remove('open');
          menuOpen = false;
      }
  })
` 

it keeps giving me an error message of cant read property of null at the const menu = document.querySelector('.menu_button') line.

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener') at Navbar (Navbar.jsx:17:1) at renderWithHooks (react-dom.development.js:14985:1)

here's the complete component.


`import Toggle from "../Toggle/Toggle";
import "./Navbar.css";
import {Link} from 'react-scroll'





const Navbar = () => {

  const menu = document.querySelector('.menu_button');
  const showMenu = document.querySelector('.mobile-nav');
  let menuOpen = false;

  console.log(menu);
  
  menu.addEventListener('click', () => {
      if(!menuOpen){
          menu.classList.add('close');
          showMenu.classList.add('open');
          menuOpen= true;
      } else {
          menu.classList.remove('close');
          showMenu.classList.remove('open');
          menuOpen = false;
      }
  })




  return (
    <div className="n-wrapper" id="Navbar">
      {/* left */}
      <div className="n-left">
        <div className="n-name">Barr Ify</div>
        <Toggle />
      </div>
      {/* right */}
      <div className="n-right">
        <div className="n-list">
              <ul >

              <Link activeClass="active" to="Navbar" spy={true} smooth={true}>

                <li>
                    Home
                </li>

                </Link>

                <Link to="services" spy={true} smooth={true}>

                <li>
                    Services
                </li>

                </Link>

                <Link to="experience" spy={true} smooth={true}>

                <li>
                    Experience
                </li>

                </Link>

                <Link to="portfolio" spy={true} smooth={true}>

                <li>
                    Portfolio
                </li>

                </Link>

                <Link to="testimonial" spy={true} smooth={true}>

                <li>
                    Testimonial
                </li>

                </Link>

              <div className="menu-wrapper">


              <div className="menu_button">
                    <div className="bars"></div>
                </div>

              </div>
              </ul>
              

              </div>


{/* Mobile Nav */}


<div className="mobile-nav">
              <ul className="mobile-lists">
              <Link activeClass="active" to="Navbar" spy={true} smooth={true}>
                <li>
                    Home
                </li>
                </Link>
                <Link to="services" spy={true} smooth={true}>
                <li>
                    Services
                </li>
                </Link>
                <Link to="experience" spy={true} smooth={true}>
                <li>
                    Experience
                </li>
                </Link>
                <Link to="portfolio" spy={true} smooth={true}>
                <li>
                    Portfolio
                </li>
                </Link>
                <Link to="testimonial" spy={true} smooth={true}>
                <li>
                    Testimonial
                </li>
                </Link>
              </ul>
              
              <Link to="contact" spy={true} smooth={true}>
                      
                      <button className="button mobile-nav-button">Contact</button>
              
              </Link>
              </div>








              <Link to="contact" spy={true} smooth={true}>
                      
                      <button className="button n-button">Contact</button>
              
              </Link>
              
              </div>

              {/* Mobile Nav */}

              

              

    </div>
  );
};

export default Navbar;
`

Solution

  • You're trying to use vanilla JS DOM manipulation within a React component, which can lead to issues because React manages the DOM for you. When you're working with React, it's best to use the built-in features and hooks to manipulate the DOM, rather than querying and modifying elements directly.

    You should learn about and use the useRef and useState hooks from React.

    Using these hooks, you can create references to your DOM elements, and manage the state of your component. Then, you can create a function to handle the click event and update the state accordingly and finally use the ref attribute to link your references to the appropriate elements and the onClick attribute to add the click event handler. I hope you will handle changes in your code by yourself without community support - because you need it, first read, try, and if nothing helps - come back =) But im sure you you'll handle it! Good luck!