ReactJS开发手风琴菜单如何实现展开一项时自动关闭其余项
核心问题分析
你目前的实现中每个ListItem都独立维护自身的展开状态,组件间状态互不可见,因此无法实现展开一个时自动关闭其他项的效果。我们需要把展开状态提升到公共父组件Menu2中统一管理即可解决。
调整后的完整代码
原有CSS不需要改动:
.accordion-cnt { display: none; } .accordion-cnt.on { display: block; }
JSX代码调整如下:
// 子组件不再维护独立状态,通过props接收控制参数 const ListItem = (props) => { const { id, isActive, onToggle } = props; return ( <li className={`accordion-item ${isActive ? "on" : ""}`}> <button onClick={() => onToggle(id)}> title </button> <div className={`accordion-cnt ${isActive ? "on" : ""}`}> content </div> </li> ); }; const Menu2 = () => { // 父组件存储当前激活的菜单项id,null代表所有项都关闭 const [activeId, setActiveId] = React.useState(null); const handleToggle = (currentId) => { // 如果点击的是已经激活的项就关闭,否则切换为当前点击的项 setActiveId(activeId === currentId ? null : currentId); // 如果不需要点击已展开项可关闭的效果,直接写成 setActiveId(currentId) 即可 }; return ( <> <ul className="accordion-list"> <ListItem id={1} isActive={activeId === 1} onToggle={handleToggle} /> <ListItem id={2} isActive={activeId === 2} onToggle={handleToggle} /> <!-- 后续新增菜单项只要按规则传id参数即可 --> </ul> </> ); };
逻辑说明
父组件统一存储当前激活项的唯一ID,每次点击某个菜单项时,只会把激活ID更新为当前点击项的ID,其余所有项的激活状态判断都会为false,自动关闭,自然就实现了互斥展开的效果。如果需要扩展更多菜单项,只要给每个ListItem传入唯一的id参数即可。
内容的提问来源于stack exchange,提问作者user1833620
相关产品推荐
相关产品推荐

