如何在不使用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
相关产品推荐
相关产品推荐

