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

ReactJS侧边栏多下拉菜单点击时全部展开问题求助

问题原因

你现在所有下拉菜单共用了同一个open布尔状态,只要这个状态变化,所有菜单的展开/收起状态都会同步改变,导致点击任意菜单都会触发全部展开。

解决方案

把单个布尔状态改成记录当前展开菜单的唯一标识(比如菜单的id,如果没有id可以用循环的index),让每个菜单独立判断自己的展开状态:

步骤1:修改状态定义

将原来的单个open状态替换为记录展开标识的状态:

// 如果你的菜单数据有唯一id,优先用id;没有的话用index
const [openId, setOpenId] = useState(null);

步骤2:修改点击逻辑

点击菜单时,切换当前展开的标识:如果当前菜单已经展开,就收起(设为null),否则展开当前菜单:

// 用id的情况(假设item有id字段)
onClick={() => setOpenId(openId === item.id ? null : item.id)}

// 用index的情况
onClick={() => setOpenId(openId === index ? null : index)}

步骤3:修改子菜单的显示判断

让子菜单根据当前菜单的标识是否匹配openId来决定是否展开:

// 用id的情况
className={openId === item.id ? 'sub-menu sub-menu-open' : 'sub-menu'}

// 用index的情况
className={openId === index ? 'sub-menu sub-menu-open' : 'sub-menu'}

修正拼写错误

原代码里的chidren是拼写错误,应该改成children,否则子菜单无法正常渲染。

修改后的完整代码

const SidebarItems = ({ items }) => {
    // 用index作为标识,若item有id则替换成item.id
    const [openId, setOpenId] = useState(null);

    return (
        <div>
            {items && items.map((item, index) => {
                return (
                    <div key={index}>
                        <div>
                            <li>
                                <div 
                                    className="nav-items" 
                                    onClick={() => setOpenId(openId === index ? null : index)}
                                >
                                    <span>
                                        <i className="bi-badge-vr" />
                                        {item.title}
                                    </span>
                                    <i className="bi-chevron-down" />
                                </div>
                            </li>
                        </div>

                        <div 
                            className={openId === index ? 'sub-menu sub-menu-open' : "sub-menu"}
                        >
                            {item.children && item.children.map((sub_menu, sub_index) => {
                                return (
                                    <div key={sub_index}> {/* 这里建议用sub_menu的id或sub_index,不要直接用sub_menu对象当key */}
                                        <Link to="manager/staff/create">
                                            <span>
                                                <i className="bi-badge-vr" />
                                                {sub_menu.title}
                                            </span>
                                        </Link>
                                    </div>
                                )
                            })}
                        </div>
                    </div>
                )
            })}
        </div>
    )
}

额外提醒:key属性尽量不要用对象(原代码里key={sub_menu}),建议用sub_index或者子菜单的唯一id,避免React渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:16:25