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

Material UI如何实现点击时仅打开对应单个下拉菜单而非全部展开

问题根源

你当前所有下拉菜单共用全局的open = Boolean(anchorEl)判断逻辑,循环渲染的所有Menu组件只要检测到anchorEl有值就会被判定为展开状态,没有区分当前点击的具体菜单项,因此点击任意按钮都会触发所有菜单同步展开。

修复方法

新增状态存储当前激活菜单的唯一标识,仅当锚点元素存在 且 菜单标识与当前激活标识匹配时,才展开对应菜单。
需要调整的细节:

  • 新增activeMenuId状态,记录被点击的菜单ID
  • 点击事件触发时,同时保存锚点元素和对应菜单的ID
  • 菜单关闭时,同时清空锚点元素和激活菜单ID
  • 每个菜单的展开状态、按钮的无障碍属性(aria-controls/aria-expanded)都要基于当前菜单自身的匹配状态判断,不能复用全局统一的open值
  • 循环渲染的根节点不要使用无key的空标签,替换为带key属性的React.Fragment,避免React抛出key缺失警告

修正后的完整代码:

const NavBarMainMenu = () => {
  const [anchorEl, setAnchorEl] = useState(null)
  const [activeMenuId, setActiveMenuId] = useState(null)

  // 判断指定ID的菜单是否处于展开状态
  const isCurrentMenuOpen = (menuId) => Boolean(anchorEl) && activeMenuId === menuId

  const handleClick = (event, menuId) => {
    setAnchorEl(event.currentTarget)
    setActiveMenuId(menuId)
  }

  const handleClose = () => {
    setAnchorEl(null)
    setActiveMenuId(null)
  }

  return (
    <Box sx={{ flexGrow: 1, display: { xs: "none", lg: "flex" } }}>
      {pages.map(page => {
        const menuOpen = isCurrentMenuOpen(page.title)
        return (
          <React.Fragment key={page.title}>
            <Button
              id={`${page.title}-button`}
              onClick={(e) => handleClick(e, page.title)}
              aria-controls={menuOpen ? page.title : undefined}
              aria-haspopup="true"
              aria-expanded={menuOpen ? "true" : undefined}
            >
              {page.title}
            </Button>
            <Menu
              anchorEl={anchorEl}
              id={page.title}
              open={menuOpen}
              onClose={handleClose}
              onClick={handleClose}
              transformOrigin={{ horizontal: "right", vertical: "top" }}
              anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
            >
              {page.children.map(child => (
                <MenuItem key={child.title}>{child.title}</MenuItem>
              ))}
            </Menu>
          </React.Fragment>
        )
      })}
    </Box>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:45:32