0

I have two files, header.js and toggle.js. I'm trying to change the class name of one of the elements in the parent component.

How can I add the active class to my <ul className="nav-wrapper"> when the button is clicked?

Here's my code:

header.js

const Header = ({ siteTitle, menuLinks,  }) => (
<header className="site-header">
    <div className="site-header-wrapper wrapper">
      <div className="site-header-logo">
        <Link to="/" className="brand">Brand Logo</Link>
      </div>
      <div className="site-header-right">
        <nav className="nav">
          <Toggle />
          <ul className="nav-wrapper">
            {menuLinks.map(link => (
              <li 
              key={link.name}
              className="nav-item"
              >
              <Link to={link.link}>
                {link.name}
              </Link>
              </li>
            ))}
          </ul>
        </nav>
      </div>

    </div>
  </header>

)

Header.propTypes = {
  siteTitle: PropTypes.string,
}

Header.defaultProps = {
  siteTitle: ``,
}

export default Header

toggle.js

  export default function Toggle() {
  const [isActive, setActive] = useState("false");

  const handleToggle = () => {
    setActive(!isActive);
  };

  return (
    <button 
    className="nav-toggle" 
    className={isActive ? "app" : null} 
    onClick={handleToggle}
    aria-expanded="false" 
    type="button">
        MENU
    </button>
  );
}

Thanks for any help!

1 Answer 1

1

Easiest way will be refactoring your code to have the useState in the Header component and then passing that state to your Toggle component as props. This will make the isActive prop available in the header so you can do something like this:

const Header = ({ siteTitle, menuLinks,  }) => {
 const [isActiveNav, setActiveNav] = useState(false);
 const activeClass  = isActiveNav ? 'active' : ''

 return (

  // All your jsx
  <Toggle isActive={isActiveNav} setActive={setActiveNav}  />
  <ul className={`nav-wrapper ${activeClass}`}>
    {// More JSX}
  </ul>
 )

Now in your Toggle component

  export default function Toggle({ isActive, setActive }) {

   const handleToggle = () => {
    setActive(!isActive);
   };

   return (
    <button 
     className="nav-toggle" 
     className={isActive ? "app" : ''} 
     onClick={handleToggle}
     aria-expanded={isActive}
     type="button">
     MENU
    </button>
   );
  }

I did some changes in your code:

  • Don't use null as a className, use an empty string instead
  • The useState value should be false not "false".
  • You can pass the isActive value to the aria-expanded prop.

This will do the trick, and is the easiest approach.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks. i keep getting 10:3 error Expected an assignment or function call and instead saw an expression no-unused-expressions after implementing your code
in /src/components/header.js
found the issue. i didn't have the return() in my header.js

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.