You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现React中点击单个Question组件仅展示对应答案?

解决FAQ点击展开所有答案的问题

你的问题在于Question组件里只用了一个布尔值状态show控制所有答案的显示/隐藏,点击任意问题时所有答案都会同步切换。要实现点击单个问题仅展开对应答案的效果,需要把状态改成记录当前激活的问题唯一标识,而非全局布尔值。

修改方案

  1. 将状态从show(布尔值)改为activeQuestionId(记录当前展开的问题ID,初始值设为null表示无展开项)
  2. 点击事件改为切换当前激活的问题ID:若点击的问题已处于激活状态则关闭,否则设置为当前问题的ID
  3. 渲染Answer组件时,判断当前问题的ID是否等于激活ID,以此决定是否显示答案

修改后的代码

function Question(props) {
    // 用activeQuestionId记录当前展开的问题ID,初始为null
    const [activeQuestionId, setActiveQuestionId] = useState(null);

    // 点击事件接收当前问题的id作为参数
    const handleQuestionClick = (questionId) => {
        // 切换激活状态:已激活则关闭,未激活则展开
        setActiveQuestionId(prevId => prevId === questionId ? null : questionId);
    };

    const questionList = props.questionList;
    const questions = questionList.map(question => (
        // 添加唯一key,优先用question.id,无id时可临时用index(生产环境建议补全唯一id)
        <div 
            key={question.id} 
            onClick={() => handleQuestionClick(question.id)} 
            className="container"
        >
            <div className="line"></div>
            <div className="question-container">
                <h3 className="question">{question.question}</h3>
                <div className="drop-icon">
                    <i className="fa-solid fa-caret-down"></i>
                </div>
            </div>

            // 仅当前问题ID匹配激活ID时显示答案
            {activeQuestionId === question.id ? <Answer question={question} /> : null}
        </div>
    ));
    return <section>{questions}</section>;
}

function Answer(props) {
    const question = props.question;
    return (
        <div className="answer">
            <p>{question.answer}</p>
        </div>
    );
}

注意事项

  • 确保questionList中的每个问题对象都有唯一id属性,若没有可临时用index替代(但生产环境建议补全唯一标识,避免列表重排时的渲染异常)
  • 点击事件通过箭头函数传递question.id,保证每个问题的点击逻辑能正确关联自身标识

内容的提问来源于stack exchange,提问作者tices

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 22:10:41