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

Next.js中如何通过点击函数实现手风琴菜单三种状态管理

实现Next.js手风琴菜单的三种状态

当前代码仅通过单个状态跟踪打开的菜单,无法区分“最近关闭”的状态。需要新增状态记录最近关闭的菜单ID,通过判断菜单ID与两个状态的关系来应用对应的CSS类。

修改后的组件代码

export default function Menu() {
  const context = useContext(navItems);
  const listItems = context.listItems;
  // 跟踪当前打开的菜单ID和最近关闭的菜单ID
  const [openItemId, setOpenItemId] = useState(null);
  const [recentClosedItemId, setRecentClosedItemId] = useState(null);

  function selectItemHandler(id) {
    if (id === openItemId) {
      // 点击已打开的菜单,关闭它并标记为最近关闭
      setOpenItemId(null);
      setRecentClosedItemId(id);
    } else {
      // 点击未打开的菜单,打开它并清除最近关闭标记
      setOpenItemId(id);
      setRecentClosedItemId(null);
    }
  }

  return (
    <>
      {listItems.map((menuItems) => {
        let itemClass;
        if (menuItems.id === openItemId) {
          itemClass = styles.mainLi_open;
        } else if (menuItems.id === recentClosedItemId) {
          itemClass = styles.mainLi_recentOpen;
        } else {
          itemClass = styles.mainLi_default;
        }

        return (
          <ul key={menuItems.id} className={`${styles.list}`}>
            <li
              id={menuItems.id}
              className={`${styles.mainLi} ${itemClass}`}
              onClick={() => selectItemHandler(menuItems.id)}
            >
              <div className={`${styles.options}`}>
                <span>{menuItems.icon}</span>
                <span>{menuItems.title}</span>
                <span>
                  <IoIosArrowDown />
                </span>
              </div>
              <ul className={styles.subMenu}>
                {menuItems.subItems.map((subitem) => (
                  <li key={subitem.id}>
                    <Link href={subitem.path}>{subitem.title}</Link>
                  </li>
                ))}
              </ul>
            </li>
          </ul>
        );
      })}
    </>
  );
}

关键逻辑说明

  • 新增recentClosedItemId状态,专门记录刚刚被关闭的菜单ID
  • 点击事件处理:
    • 若点击的是当前打开的菜单,关闭它并将其ID存入recentClosedItemId
    • 若点击的是其他菜单,打开目标菜单并清空recentClosedItemId(让之前的菜单回到默认状态)
  • 类名判断:优先匹配打开状态,其次匹配最近关闭状态,最后使用默认状态

CSS样式说明

你已定义的三种状态样式无需修改,当前逻辑会自动根据状态切换对应的CSS类:

  • .mainLi_default:菜单未被点击过的默认状态
  • .mainLi_open:首次点击后打开的状态
  • .mainLi_recentOpen:点击已打开的菜单关闭后的状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:11:00