React State Hook - 切换 class

React State Hook - toggle a class

我正在尝试构建侧边栏导航菜单,并认为我会利用 React 中的新状态挂钩。我已经阅读了文档,但似乎找不到与我需要的类似的示例,这很简单,只需在单击时切换 CSS class 即可打开和关闭我的菜单。

这是我尝试过的方法:

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;

有什么地方出错了吗?

谢谢

我想你只需要

const [ menuActive, setMenuState ] = useState(false);

在您的代码中也将 setState 的名称更改为 setMenuState

只需将 className 设置为动态名称,而不是设置

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

将其转换为模板文字

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

然后有条件地添加您的 class(在我的示例中为 "yellow" class)

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

看看这个 CodeSandbox:我刚刚添加了您的组件并更改了 className 属性的生成方式。

如果您想避免使用三元运算符,您可以使用 classnames module 然后将代码更新为

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

另一种干净的解决方案是预先生成 className 字符串,例如

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

如果您需要更多帮助,请告诉我

不要忘记使用 prevState,否则会出现错误。

<button
  className="p-sidebar-menu-item__link"
  onClick={() => setMenuState((prevMenuActive) => !prevMenuActive)}>
{component.component}
</button>