React组件中手风琴独立展开折叠状态控制问题求助
解决方案
问题出在你用了单个布尔值isActive作为所有手风琴项的状态,导致所有组件共享同一状态,点击时会同时切换。要保留状态在App组件且实现单个项独立展开/折叠,只需把状态改为记录当前激活项的唯一标识(比如索引、id),而非全局布尔值。
修改后的App组件代码
import React, { useState } from "react"; import Accordion from "./Accordion"; const App = () => { // 用null表示初始无激活项,或设为0默认展开第一个 const [activeItemIndex, setActiveItemIndex] = useState(null); const accordionData = [ { title: "Section 1", content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis` }, { title: "Section 2", content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis` }, { title: "Section 3", content: `Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quis` } ]; return ( <div> <h1>React Accordion Demo</h1> <div className="accordion"> {accordionData.map(({ title, content }, index) => ( <Accordion key={index} activeItemIndex={activeItemIndex} setActiveItemIndex={setActiveItemIndex} itemIndex={index} title={title} content={content} /> ))} </div> </div> ); }; export default App;
修改后的Accordion组件代码
import React from "react"; const Accordion = ({ title, content, activeItemIndex, setActiveItemIndex, itemIndex }) => { // 判断当前项是否为激活状态 const isActive = activeItemIndex === itemIndex; const handleToggle = () => { // 点击已激活的项则折叠,否则激活当前项 setActiveItemIndex(activeItemIndex === itemIndex ? null : itemIndex); }; return ( <div className="accordion-item"> <div className="accordion-title" onClick={handleToggle}> <div>{title}</div> <div>{isActive ? "-" : "+"}</div> </div> {isActive && <div className="accordion-content">{content}</div>} </div> ); }; export default Accordion;
核心修改说明
- 状态存储方式变更:App组件用
activeItemIndex记录当前激活项的索引(也可以用每项的唯一id,更推荐),替代原来的全局布尔值。 - 独立状态判断:每个Accordion组件通过
itemIndex和activeItemIndex对比,确定自身是否展开。 - 切换逻辑优化:点击时判断当前项是否已激活,实现“点击已展开项则折叠,点击未展开项则展开(同时折叠其他项)”的交互。
如果需要支持多项同时展开,只需把状态改成数组存储激活的索引,点击时添加/移除对应索引即可,状态仍保留在App组件中。
内容的提问来源于stack exchange,提问作者Rio
相关产品推荐
相关产品推荐

