0

I am trying to build a toggle sidebar. when I click on the button the class list of .m-toggle should be updated. But react gives me an error

"TypeError: Cannot read property 'classList' of null"

Here is my code:

import React, { useState, useEffect } from 'react'
// import Sidebar from '../Components/Sidebar'
import AppleIcon from '@material-ui/icons/Apple'
import DashboardIcon from '@material-ui/icons/Dashboard'
import PeopleIcon from '@material-ui/icons/People'
import NotificationsIcon from '@material-ui/icons/Notifications'
import SettingsIcon from '@material-ui/icons/Settings'
import HelpIcon from '@material-ui/icons/Help'
import img from '../Assets/img/keval.jpg'

function toggleMenu() {
  let toggle = document.querySelector('.m-toggle')
  toggle.classList.toggle('m-active')
}

const Main = () => {
  return (
    <>
      <div className="m-body">
        <div className="m-container">
          {/* -------Sidebar Start------- */}
          <div className="m-navigation">
            <ul style={{ padding: '0' }}>
              <li>
                <a href="#">
                  <span className="m-icon">
                    <AppleIcon className="muicon" />
                  </span>
                  <span className="m-title">
                    <h2>Brand Name</h2>
                  </span>
                </a>
                <hr style={{ color: 'white' }} />
              </li>
              <li>
                <a href="#">
                  <span className="m-icon">
                    <DashboardIcon className="muicon" />
                  </span>
                  <span className="m-title">Dashboard</span>
                </a>
              </li>
              <li>
                <a href="#">
                  <span className="m-icon">
                    <PeopleIcon className="muicon" />
                  </span>
                  <span className="m-title">Employees</span>
                </a>
              </li>
              <li>
                <a href="#">
                  <span className="m-icon">
                    <NotificationsIcon className="muicon" />
                  </span>
                  <span className="m-title">Notification</span>
                </a>
              </li>
              <li>
                <a href="#">
                  <span className="m-icon">
                    <HelpIcon className="muicon" />
                  </span>
                  <span className="m-title">Help</span>
                </a>
              </li>
              <li>
                <a href="#">
                  <span className="m-icon">
                    <SettingsIcon className="muicon" />
                  </span>
                  <span className="m-title">Setting</span>
                </a>
              </li>
            </ul>
          </div>
          {/* --------Side BAr End--------- */}
          <div className="m-main">
            <div className="m-topbar">
              <div className="m-toggle" onClick={toggleMenu()}>
                f
              </div>
              <div className="m-search">
                <label>
                  <input type="text" placeholder="Search here" />
                </label>
              </div>
              <div className="user">
                <img src={img} alt="no img" />
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  )
}

export default Main

You can see the code where onclick class list should be updated but it is not updating.

4
  • 2
    "Document query selector returns undefined..." (which won't ever be the case) but then "Type Error: Can not read property ClassList Of Null". The title should give a proper summary of the actual problem and not a "might describe the situation good enough" Commented May 15, 2021 at 11:45
  • It might be that in a stylesheet you use display: none for .m-toggle or a parent element. If you want to get the element via querySelector you need to use visibility: hidden Commented May 15, 2021 at 11:50
  • 1
    It's because you do this onClick={toggleMenu()} which calls the function immediately even before mount. You should use onClick={toggleMenu} Commented May 15, 2021 at 11:53
  • ... and as the click event is fired on the .m-toggle element, you won't need to use querySelector, because this already refers to the element Commented May 15, 2021 at 11:58

3 Answers 3

1

One problem I see is that you are not passing a function reference in onClick, but doing a function call instead:

<div className="m-toggle" onClick={toggleMenu()}>

Either remove the parentheses after toggleMenu:

<div className="m-toggle" onClick={toggleMenu}>

or pass it as an inline arrow function:

<div className="m-toggle" onClick={() => toggleMenu()}>
Sign up to request clarification or add additional context in comments.

Comments

1

Several problems:

  1. React onClick expects a function but you are invoking toggleMenu instead. It should be onClick={toggleMenu} or onClick={()=>toggleMenu()}
  2. You should be managing the className using state instead of using document.querySelector() and modifying the element yourself.

Comments

1

You are calling the toggleMenu() method during component render which you shouldn't do. So when your component tries to render, it calls toggleMenu method and returns null for m-toggle query selector. you can either bind function reference or use arrow function.

<div className="m-toggle" onClick={toggleMenu}>

OR

<div className="m-toggle" onClick={() => toggleMenu()}>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.