React组件map渲染列表时切换active类会作用于所有列表项问题
问题原因
你当前的实现把激活状态存在一个全局布尔值isActive里,所有通过map遍历生成的<li>元素都共用这一个状态:只要isActive为true,所有li的className判断条件都会成立,自然会同时给所有元素加上active类,没法区分具体选中的是哪个菜单项。
修复方案
不要用布尔值存激活状态,改为存储当前选中菜单项的唯一标识(比如菜单项的name字段,也可以自己给每个菜单项加唯一id),渲染时逐个判断当前遍历项的标识和状态里存的选中标识是否一致,匹配才加active类。
具体修改点
- 调整state定义,存储当前选中的菜单项标识,默认可以选中第一个菜单,也可以设为空不默认选中
- 修改点击回调,点击时传入当前菜单项的标识,更新状态为当前点击项
- 调整li的className判断逻辑,只有当前项标识和状态存储的选中标识一致时,才加active类
- 补全列表遍历要求的唯一key属性,消除React控制台警告
- 修正原代码里Free Data菜单项图标class多余的转义字符,避免图标显示异常
- 如果是单页应用不需要点击菜单触发整页刷新,可以在a标签点击事件里阻止默认跳转行为
修复后完整代码
import '../../Utility/css/sidebar.css'; import 'bootstrap/dist/css/bootstrap.min.css'; import { useState } from "react"; export default function Sidebar(){ // 存储当前选中的菜单name,默认选中Home,不需要默认选中就把初始值设为null const [activeMenu , setActiveMenu] = useState('Home'); // 接收传入的当前点击菜单name,更新选中状态 const toggleClass = (menuName) => { setActiveMenu(menuName); } const sideMenuJson =[ { name :'Home', pass:'inbox', pass2:'fa fa-home', spanclass:'icon-bg rad-bg-success' }, { name :'Free Data', pass:'', pass2:'fa fa-shopping-cart', spanclass:'icon-bg rad-bg-danger' }, { name :'Paid Data', pass:'snooz', pass2:'fa fa-line-chart', spanclass:'icon-bg rad-bg-primary' }, { name :'Order', pass:'done', pass2:'fa fa-area-chart', spanclass:'icon-bg rad-bg-warning' }, { name :'Transaction', pass:'', pass2:'fa fa-wrench', spanclass:'icon-bg rad-bg-violet' }, { name :'Profile', pass:'', pass2:'fa fa-wrench', spanclass:'icon-bg rad-bg-violet' } ]; return ( <nav className="rad-sidebar primary-bg-color"> <ul className="list-unstyled"> { sideMenuJson.map(item => <li key={item.name} className={activeMenu === item.name ? "active": null} onClick={() => toggleClass(item.name)} > <a href="/" className={item.pass} onClick={(e) => e.preventDefault() /* 不需要整页跳转就保留这行 */} > <i className={item.pass2}> <span className={item.spanclass}></span> </i> <span className="rad-sidebar-item">{item.name}</span> </a> </li> ) } </ul> </nav> ) }
内容的提问来源于stack exchange,提问作者texter
相关产品推荐
相关产品推荐

