Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React State Hook - toggle a class

I'm trying to build a sidebar navigation menu and thought I'd take advantage of the new State hook in React. I've read the docs but can't seem to find an example similar to what I need, which is quite simply to toggle a CSS class on click which will in turn open and close my menu.

Here's what I've tried:

const SidebarMenuItem = ({ component }) => {
  const [ menuActive, setMenuState ] = useState(false);

  return (
    <li className="p-sidebar-menu-item">
      menuActive:
      { menuActive }
      <button className="p-sidebar-menu-item__link" onClick={() => setMenuState(!menuActive)}>{ component.component }</button>
      { component.children && (
        <ul className="p-sidebar-menu">
          <li><a href={`/${component.slug}`}>Overview</a></li>
          { component.children.map((subPage, key) => (
            <li key={ key }>
              <a href={`/${subPage.slug}`}>{ subPage.name }</a>
            </li>
          ))}
        </ul>
      )}
    </li>
  )
}

export default SidebarMenuItem;

Any ideas where I'm going wrong?

Thanks

like image 594
James Howell Avatar asked Apr 09 '19 16:04

James Howell


1 Answers

Just make the className dynamic, so instead of setting

<li className="p-sidebar-menu-item">

transform it in a template literal

<li className={`p-sidebar-menu-item`}>

and then add your class conditionally (the "yellow" class in my example)

<li className={`p-sidebar-menu-item ${menuActive ? "yellow" : ""}`}>

Take a look at this CodeSandbox: here I've just added your component and changed the way the className attribute is generated.

If you want to avoid the ternary operator you could use the classnames module and then update your code to

import c from "classnames";
...
...
...
<li className={c("p-sidebar-menu-item", {yellow: menuActive})}>

Another clean solution can be to generate the className string in advance, for example

let classes = "p-sidebar-menu-item";
if(menuActive) {
  classes += " yellow";
}
<li className={classes}>

Let me know if you need some more help 😉

like image 173
NoriSte Avatar answered Sep 28 '22 05:09

NoriSte