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

如何在不使用Redux的情况下实现侧边菜单的展开保持与互斥关闭?

实现侧边菜单保持展开(无需Redux)的方案

完全可以不用Redux实现,核心是靠React的内置状态(useState)跟踪每个菜单的展开状态,替代原代码里直接操作DOM类名的方式,就能轻松实现菜单保持展开、互不影响的效果。

问题出在哪?

原代码的Dep2Handler点击菜单时,会把所有兄弟节点的on类都移除,导致同一时间只能有一个菜单展开。要实现菜单能保持展开,得改成单独控制每个菜单的展开/折叠状态,不能搞全局互斥那套。

修改后的完整代码

import { useState } from 'react';

const Sidebar = () => {
  // 用对象存每个菜单的展开状态,键是菜单的唯一标识
  const [expandedMenus, setExpandedMenus] = useState({
    menu1: false,
    menu2: false
  });

  // 二级菜单点击:切换当前菜单的展开状态,不碰其他菜单
  const Dep2Handler = (menuKey) => {
    setExpandedMenus(prev => ({
      ...prev,
      [menuKey]: !prev[menuKey]
    }));
  };

  // 三级菜单点击:只高亮当前选中项,不改变父菜单的展开状态
  const Dep3Handler = (e) => {
    // 先清除同级别所有li的选中状态
    const siblingItems = e.target.parentElement.parentElement.children;
    Array.from(siblingItems).forEach(item => item.classList.remove("on"));
    // 给当前点击的li加上选中类
    e.target.parentElement.classList.add("on");
  };

  return (
    <ol>
      <li className={expandedMenus.menu1 ? "on" : ""}>
        <p onClick={() => Dep2Handler("menu1")}></p>
        <ol className="has_dep3">
          <li onClick={Dep3Handler} value="space">
            <button className="btn" onClick={() => history("/info")}></button>
          </li>
          <li onClick={Dep3Handler} value="equip">
            <button className="btn" onClick={() => history("/info/info/equipinfo")}></button>
          </li>
          <li onClick={Dep3Handler} value="work">
            <button className="btn" onClick={() => history("/info/info/workerinfo")}></button>
          </li>
        </ol>
      </li>
      <li className={expandedMenus.menu2 ? "on" : ""}>
        <p onClick={() => Dep2Handler("menu2")}></p>
        <ol className="has_dep3">
          <li onClick={Dep3Handler}>
            <button onClick={() => history("/admin/info/greetings")}></button>
          </li>
          <li onClick={Dep3Handler}>
            <button onClick={() => history("/admin/info/vision")}></button>
          </li>
          <li onClick={Dep3Handler}>
            <button onClick={() => history("/admin/info/organization")}></button>
          </li>
          <li onClick={Dep3Handler}>
            <button onClick={() => history("/admin/info/partner")}></button>
          </li>
        </ol>
      </li>
      <li>
        <p onClick={() => history("/info/way")}></p>
      </li>
      <li>
        <p onClick={() => history("/info/faq")}></p>
      </li>
    </ol>
  );
};

重点说明

  • 用expandedMenus对象单独记录每个菜单的展开状态,每个菜单的状态互不干扰,想展开几个就展开几个
  • 点击二级菜单时只切换自身状态,不会关闭其他已经展开的菜单
  • 三级菜单点击只处理选中高亮,父菜单的展开状态保持不变
  • 全程用React自带的useState实现,完全不需要Redux

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 22:20:41