如何实现React Bootstrap Collapse仅保持一个项展开?
实现React折叠组件的单选展开(仅保持一个项展开)
当前问题:每个Example组件自己维护独立的open状态,点击不同组件时状态互不干扰,会出现多个折叠项同时展开的情况。要实现点击新项时自动关闭已展开项,始终只留一个展开,需要把状态提升到父组件统一管理。
修改思路与步骤
- 将子组件的状态移到父组件,用一个变量记录当前展开的项ID
- 子组件改为接收父组件传入的「是否展开」状态和「点击切换」回调
- 给每个子组件分配唯一ID,既用来区分身份,也避免DOM元素ID重复
修改后的代码
子组件(Example)
import { Button, Collapse } from 'react-bootstrap'; function Example({ id, isOpen, onToggle }) { return ( <> <Button onClick={() => onToggle(id)} aria-controls={`example-collapse-text-${id}`} aria-expanded={isOpen} className="Collapse-Test" data-open={isOpen} > click </Button> <Collapse in={isOpen}> <div id={`example-collapse-text-${id}`}> Hidden Text for Item {id} </div> </Collapse> </> ); };
父组件(调用多个Example的容器)
import { useState } from 'react'; import Example from './Example'; function CollapseGroup() { // activeId记录当前展开的项ID,初始为null表示全部收起 const [activeId, setActiveId] = useState(null); const handleToggle = (id) => { // 点击已展开的项就关闭,否则切换到该项展开 setActiveId(prevId => prevId === id ? null : id); }; return ( <> <div><Example id="1" isOpen={activeId === "1"} onToggle={handleToggle} /></div> <div><Example id="2" isOpen={activeId === "2"} onToggle={handleToggle} /></div> <div><Example id="3" isOpen={activeId === "3"} onToggle={handleToggle} /></div> </> ); };
核心说明
- 父组件的
activeId统一控制所有子组件的展开状态,确保同一时间只有一个项的isOpen为true - 修改了子组件的DOM元素ID,通过拼接唯一ID避免重复,符合网页规范
- 点击逻辑集中在父组件的
handleToggle,实现了单选展开的控制逻辑
内容的提问来源于stack exchange,提问作者JPWilson
相关产品推荐
相关产品推荐

