You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React单State控制子菜单:实现点击仅展开对应子菜单

问题:React导航菜单点击后仅展开当前项的子菜单

当前使用单个布尔值状态ShowSubMenu控制所有子菜单的展开/收起,导致点击任意一项时所有子菜单都会同步展开或收起。需求是点击某一项时仅展开对应的子菜单,且不想为每个导航项单独声明useState。

导航数据如下:

const navigation = [
  {
    name: "Services",
    description: "Our services",
    href: "#",
    subMenu: [
      { name: "Management" },
      { name: "Development" },
      { name: "Specialists" },
    ],
  },
  {
    name: "Experts",
    description: "our experts",
    href: "#",
    subMenu: [
      { name: "Engineers" },
      { name: "Project managers" },
      { name: "Developers" },
      { name: "Cloud solutions" },
    ],
  }, 
];

解决方案

核心思路是将状态从布尔值改为记录当前展开项的唯一标识(比如每个导航项的description,它是子菜单标题且唯一),通过判断当前项的标识是否与状态值匹配来控制子菜单的显示/隐藏。

修改后的代码:

  1. 调整状态定义:
// 用null表示初始无展开项,状态值存储当前展开项的description(或其他唯一字段)
const [expandedKey, setExpandedKey] = useState(null);
  1. 渲染部分修改:
{navigation.map((item) => (
  <>
    <div
      onClick={() => {
        // 点击时切换:如果当前项已展开则关闭,否则展开该项
        setExpandedKey(expandedKey === item.description ? null : item.description);
      }}
      className="border-b-2 justify-between pb-4 pl-2 font-bold flex"
    >
      <h3 className="text-roboto">{item.description}</h3>
      <div className="border-solid border-b-2"></div>
      <ChevronDownIcon
        // 仅当前展开项的图标旋转
        className={expandedKey === item.description ? "rotate-90 h-5 w-5" : "h-5 w-5"}
      />
    </div>

    <div className="flex flex-col">
      {item.subMenu.map((sm) => (
        <div
          key={sm.name}
          // 仅当前展开项的子菜单显示
          className={expandedKey !== item.description ? "hidden" : "pl-2 pt-2"}
        >
          {sm.name}
        </div>
      ))}
    </div>
  </>
))}

说明:

  • 状态expandedKey存储当前展开项的唯一标识(这里用description,也可以用name或其他不会重复的字段)
  • 点击导航项时,判断当前项的标识是否等于expandedKey:如果相等则设置为null(关闭),否则设置为当前项的标识(展开)
  • 子菜单和图标的显示逻辑均基于expandedKey与当前项标识的匹配关系,实现仅展开点击项的效果

内容的提问来源于stack exchange,提问作者Tihi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 10:06:22