如何使用React useState Hook管理多个元素的展开收起状态?
不需要为6张卡片分别声明6个useState,有两种更易维护、更简洁的实现方案。
方案1:使用对象类型的单一state管理所有卡片状态
将所有卡片的开关状态存在同一个对象类型的state中,key为卡片的唯一标识(索引/自定义id均可),value为对应卡片的展开状态,通过切换函数传入id修改对应状态即可。
示例代码如下:
// 初始化所有卡片状态为关闭 const [openStates, setOpenStates] = useState({ 1: false, 2: false, 3: false, 4: false, 5: false, 6: false }) // 通用切换方法,传入卡片id即可修改对应状态 const toggleCard = (cardId) => { setOpenStates(prev => ({ ...prev, [cardId]: !prev[cardId] })) } // 单张卡片调用示例,其余5张仅需修改对应id即可 <Button onClick={() => toggleCard(1)} aria-controls={`collapse-card-1`} aria-expanded={openStates[1]} > 点击 </Button> <Collapse in={openStates[1]}> <div id={`collapse-card-1`}> This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer. </div> </Collapse>
方案2:封装独立可复用的折叠卡片组件(更推荐)
将折叠卡片的逻辑封装为独立组件,组件内部自己维护展开状态,父组件仅需要传入卡片的展示内容即可,完全不需要在父组件声明任何和展开相关的state,扩展性更强。
示例代码如下:
// 封装的独立折叠卡片组件 const CollapsibleCard = ({ buttonText, content }) => { const [isOpen, setIsOpen] = useState(false) return ( <> <Button onClick={() => setIsOpen(!isOpen)} aria-controls="collapse-card-content" aria-expanded={isOpen} > {buttonText} </Button> <Collapse in={isOpen}> <div id="collapse-card-content"> {content} </div> </Collapse> </> ) } // 父组件直接调用即可,无需维护任何展开状态 <CollapsibleCard buttonText="点击" content="卡片1的内容" /> <CollapsibleCard buttonText="点击" content="卡片2的内容" /> <CollapsibleCard buttonText="点击" content="卡片3的内容" /> <CollapsibleCard buttonText="点击" content="卡片4的内容" /> <CollapsibleCard buttonText="点击" content="卡片5的内容" /> <CollapsibleCard buttonText="点击" content="卡片6的内容" />
两种方案都可以解决多卡片同时展开的问题,如果卡片逻辑后续可能新增其他交互,优先选择封装组件的方案,维护成本更低。
内容的提问来源于stack exchange,提问作者Firas SCMP
相关产品推荐
相关产品推荐

