React手风琴组件点击图标切换 仅保持单项目展开的问题求解
问题根源
你当前的实现中,每个Question子组件都独立维护了自己的isOpen展开状态,组件之间的状态完全隔离,无法实现多折叠项的互斥开关逻辑。想要实现同一时间仅展开一项的手风琴效果,需要把展开状态提到公共的父组件FAQ中统一管理。
修复后代码
import React, { useState } from "react"; import { FaPlus, FaMinus } from "react-icons/fa"; import "./FAQ.scss"; import { Collapse } from "reactstrap"; // 子组件不再维护独立状态,通过props接收父组件传递的状态和回调 const Question = (props) => { const { question, isActive, toggle } = props; return ( <div className="question"> <div> <button onClick={() => toggle(question)}> {isActive ? <FaMinus /> : <FaPlus />} </button> </div> <div onClick={() => toggle(question)} className='title'> {question} </div> <Collapse isOpen={isActive} className='content'> The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. </Collapse> <hr /> </div> ); }; function FAQ() { // 父组件统一维护当前展开的问题标识,初始为null表示全部关闭 const [activeQuestion, setActiveQuestion] = useState(null); const toggle = (targetQuestion) => { // 如果点击的是当前已经展开的问题,就关闭;否则切换为点击的问题 setActiveQuestion(activeQuestion === targetQuestion ? null : targetQuestion); }; return ( <div className="faq" id='faq'> <h2>F.A.Q.</h2> <div className="faq-section"> <Question question="Question one" isActive={activeQuestion === "Question one"} toggle={toggle} /> <Question question="Question two" isActive={activeQuestion === "Question two"} toggle={toggle} /> <Question question="Question three" isActive={activeQuestion === "Question three"} toggle={toggle} /> <Question question="Question four" isActive={activeQuestion === "Question four"} toggle={toggle} /> <Question question="Question five" isActive={activeQuestion === "Question five"} toggle={toggle} /> </div> </div> ); } export default FAQ;
逻辑说明
- 父组件FAQ通过
useState维护activeQuestion变量,记录当前处于展开状态的问题标识,初始值为null代表所有折叠项默认关闭 - 点击某一项时,将当前点击的问题标识传入公共toggle方法,判断如果是已经激活的项就关闭,否则切换为当前点击项
- 子组件Question接收父组件传递的
isActive(判断当前项是否展开)和toggle(点击触发父组件状态更新)两个props,不再维护内部独立状态
如果你的问题内容存在重复的情况,也可以给每个Question项绑定唯一id作为判断标识,逻辑完全一致。
内容的提问来源于stack exchange,提问作者Inception_K
相关产品推荐
相关产品推荐

