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

ReactJS FAQ卡片 点击已展开项无法关闭的问题排查与修复

问题原因

你的手风琴点击已展开项无法收起的bug,核心问题出在hideText函数的执行逻辑上:

  1. 你把「展开当前点击项」的判断写在了for循环内部,每轮循环都会重复执行这段逻辑
  2. 当点击已经展开的项时,循环第一轮就会给这个项加上not-active类执行收起,但紧接着同轮循环又会检测到这个项带有not-active类,马上把类移除重新展开,两个操作互相抵消,最终表现就是点击已展开项没有任何反应。
最小修改修复方案

不需要改动JSX结构,只需要重写hideText函数即可,修复后的逻辑为:

  • 先记录当前点击项的初始展开状态
  • 统一将所有答案项设置为收起状态
  • 仅当点击项初始为收起状态时,才将其设置为展开;如果初始就是展开状态,保持全部收起即可
function hideText(element) {
  // 提前记录当前点击项是否处于展开状态
  const isCurrentExpanded = !element.current.classList.contains("not-active");
  // 所有项统一收起
  elementsArray.forEach(item => {
    item.current.classList.add("not-active");
  });
  // 点击的是收起项才展开,点击展开项就保持全收起状态
  if (!isCurrentExpanded) {
    element.current.classList.remove("not-active");
  }
}
React推荐写法(可选优化)

直接操作DOM class不符合React的状态驱动设计理念,你可以用useState管理当前展开项的索引,去掉冗余的ref定义,后续新增FAQ项也更方便:

import { useState } from "react";
import img_1 from "../images/bg-pattern-desktop.svg";
import img_2 from "../images/illustration-woman-online-desktop.svg";

export default function MainContent() {
  // null代表无展开项,值为索引时代表对应索引的项展开
  const [openIndex, setOpenIndex] = useState(null);

  // FAQ配置数组,新增/修改项直接改数组即可
  const faqConfig = [
    {
      question: "How many team members can I invite?",
      answer: "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus obcaecati, quae, corporis."
    },
    {
      question: "How many team members can I invite?",
      answer: "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus obcaecati, quae, corporis."
    },
    {
      question: "How many team members can I invite?",
      answer: "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus obcaecati, quae, corporis."
    },
    {
      question: "How many team members can I invite?",
      answer: "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus obcaecati, quae, corporis."
    },
    {
      question: "How many team members can I invite?",
      answer: "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Temporibus obcaecati, quae, corporis."
    }
  ];

  const toggleFaq = (index) => {
    // 点击已展开项则收起所有,点击其他项则展开对应项
    setOpenIndex(openIndex === index ? null : index);
  };

  return (
    <>
      <div className="container">
        <div className="imgBox">
          <img src={img_1} alt="bg pattern" className="img_1" />
          <img src={img_2} alt="woman online illustration" className="img_2" />
        </div>

        <div className="textBox">
          <h1>FAQ</h1>
          <div className="questions">
            {faqConfig.map((item, index) => (
              <div key={index}>
                <button onClick={() => toggleFaq(index)}>
                  {item.question}
                </button>
                <p className={`p${index + 1} ${openIndex !== index ? "not-active" : ""}`}>
                  {item.answer}
                </p>
                {index !== faqConfig.length - 1 && <hr />}
              </div>
            ))}
          </div>
        </div>
      </div>
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 12:42:27