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

React JS菜单切换异常:点击任意Li项仅最后一个菜单展开求助

解决React菜单点击后仅最后一项展开的问题

嘿,太懂这种踩坑的憋屈感了!你遇到的这个问题,本质是状态没和单个菜单项绑定,导致所有菜单共享了同一个展开状态变量,点击时所有菜单都会触发状态变化,但最后一个可能因为渲染层级或者样式覆盖,看起来只有它展开了。

问题根源分析

你大概率是用了一个单一的布尔值状态(比如const [isOpen, setIsOpen] = useState(false))来控制所有菜单项的展开/收起。当你点击任意一个<li>时,这个全局的isOpen会切换状态,所有绑定了这个状态的子菜单都会跟着显示/隐藏——但可能因为DOM布局的原因,前面的子菜单被后面的覆盖了,所以看起来只有最后一个展开。

解决方案:给每个菜单项绑定独立的状态标识

我们需要用一个状态来记录当前展开的菜单项的唯一标识(比如id、索引),而不是用单个布尔值。这样就能精准控制只有被点击的菜单项展开。

举个具体的实现例子:

import { useState } from 'react';

function Menu() {
  // 假设你的菜单数据是这样的(可根据实际情况调整)
  const menuItems = [
    { id: 1, title: "菜单1", submenu: ["子项1-1", "子项1-2"] },
    { id: 2, title: "菜单2", submenu: ["子项2-1", "子项2-2"] },
    { id: 3, title: "菜单3", submenu: ["子项3-1", "子项3-2"] }
  ];

  // 用状态记录当前展开的菜单id,初始为null(都不展开)
  const [openMenuId, setOpenMenuId] = useState(null);

  // 点击菜单的处理函数
  const handleMenuClick = (menuId) => {
    // 如果点击的是当前已展开的菜单,就收起;否则展开它
    setOpenMenuId(prevId => prevId === menuId ? null : menuId);
  };

  return (
    <ul className="menu">
      {menuItems.map(item => (
        <li 
          key={item.id} 
          onClick={() => handleMenuClick(item.id)}
          className={openMenuId === item.id ? "active" : ""}
        >
          {item.title}
          {/* 只有当前id匹配的菜单才显示子菜单 */}
          {openMenuId === item.id && (
            <ul className="submenu">
              {item.submenu.map(subItem => (
                <li key={`${item.id}-${subItem}`}>{subItem}</li>
              ))}
            </ul>
          )}
        </li>
      ))}
    </ul>
  );
}

export default Menu;

额外小提示

  • 如果你的菜单项是静态写死的(不是从数组map出来的),也可以给每个菜单单独设置状态(比如isMenu1Open、isMenu2Open),但这种方式扩展性差,菜单项多的话不推荐。
  • 记得给每个<li>加上唯一的key属性,这是React列表渲染的要求,也能避免一些奇怪的渲染问题。

这样修改后,点击哪个菜单项,就只会展开对应的子菜单,其余的都会保持隐藏状态啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:03:02