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

如何创建带Submenu的React侧边栏及子菜单全部展开问题排查

问题根本原因

你当前的代码使用了全局统一的布尔状态(比如isOpen)控制所有子菜单的展开状态,没有为每个菜单项绑定独立的展开标识,所以任意一处触发状态变更都会同步影响所有子菜单的展示逻辑。

修复步骤
  • 第一步:调整状态定义,将布尔类型的展开状态替换为存储当前激活展开的菜单项唯一标识,支持同时仅展开一个菜单的手风琴效果:
// 以函数组件为例
import { useState } from 'react'
// 初始值设为null代表没有展开的菜单
const [activeMenuId, setActiveMenuId] = useState(null)
  • 第二步:补全accordiondata.js配置,给每个带有子菜单的父菜单项添加唯一id字段,示例如下:
// accordiondata.js
export const sidebarMenuData = [
  {
    id: 1,
    title: "数据中心",
    icon: "DashboardIcon",
    path: "/dashboard",
    submenu: [
      { title: "核心概览", path: "/dashboard/overview" },
      { title: "访问统计", path: "/dashboard/analytics" }
    ]
  },
  {
    id: 2,
    title: "内容管理",
    icon: "ContentIcon",
    path: "/content",
    submenu: [
      { title: "文章列表", path: "/content/articles" },
      { title: "分类管理", path: "/content/categories" }
    ]
  }
]
  • 第三步:修改子菜单切换的事件处理逻辑,点击时仅切换当前点击菜单项的展开状态:
const toggleSubmenu = (currentMenuId) => {
  // 如果当前点击的菜单已经是展开状态,点击后收起;否则展开当前点击的菜单
  setActiveMenuId(activeMenuId === currentMenuId ? null : currentMenuId)
}
  • 第四步:调整渲染逻辑,仅当当前菜单项的id和激活id匹配时展示子菜单:
// navbar.js 菜单渲染部分
{sidebarMenuData.map(menu => (
  <div key={menu.id} className="sidebar-menu-item">
    <div 
      className="sidebar-menu-title"
      onClick={() => toggleSubmenu(menu.id)}
    >
      {/* 这里可以放图标、标题、展开箭头 */}
      {menu.title}
    </div>
    {/* 匹配到激活id才渲染子菜单 */}
    {activeMenuId === menu.id && menu.submenu?.length > 0 && (
      <div className="sidebar-submenu">
        {menu.submenu.map(subItem => (
          <a 
            key={subItem.path} 
            href={subItem.path}
            className="sidebar-submenu-item"
          >
            {subItem.title}
          </a>
        ))}
      </div>
    )}
  </div>
))}
扩展说明

如果你需要支持同时展开多个子菜单,把状态改成Set类型存储已展开的菜单id即可,点击时往Set里添加/移除对应id,渲染时判断当前id是否在Set中。如果是多级嵌套子菜单,将状态改为存储层级id数组,对应调整判断逻辑即可适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:39:01