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

React自定义FAQ手风琴点击全部展开,如何实现单条切换?

解决React手风琴所有项同时展开的问题

问题根源是你使用了单个布尔值isActive作为所有手风琴项的展开状态,点击时会全局切换这个状态,导致所有项同步展开/收起。以下是修改方案:

修改步骤:

  1. 替换状态定义:将全局布尔状态改为记录当前展开项的索引(或唯一ID)
  2. 更新点击事件逻辑:点击时判断当前项是否已展开,切换对应索引
  3. 调整展开判断条件:根据当前项索引与活跃索引是否匹配来控制内容显示
  4. 切换加减号显示逻辑:同样基于当前项的活跃状态切换符号

修改后的完整代码:

import React, { useState, useEffect } from "react";
import axios from "axios";
const Faq = () => {
  const [faq, setFaq] = useState([]);
  // 用null表示初始无展开项,或设为0默认展开第一个
  const [activeIndex, setActiveIndex] = useState(null);

  const fetchFaqs = async () => {
    const token = sessionStorage.getItem("token");
    try {
      const res = await axios.get(
        `http://localhost/faq/allFaq`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        }
      );
      setFaq(res.data.proData);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    fetchFaqs();
  }, []); // 加空依赖数组,避免无限触发请求

  if(faq.length > 0)
  {
    return (
      <React.Fragment>
          <Navbar />
          <div className="FaqHeader">
            <div className="bhtext pt-3">
              <h1 className="pb-4">Lorem ipsum dolor sit</h1>
              <p className="hometext px-3">
                It has roots in a piece of classical Latin literature from 45 BC,
                making it over 2000 years <br /> old. Richard McClintock
              </p>
              <p className="addressbar pb-3 mb-0">
                Home <i className="fa-solid fa-chevron-right"></i> <span>Faq</span>
              </p>
            </div>
          </div>
          <div className="container-fluid faqmain">
            <div className="faqacc">
                  <div className="pt-3">
                    <div className="faqTitle">
                      <h1>Frequently Asked Questions</h1>
                    </div>
                      {faq.map((faqe, index) => {
                        return (
                          <div className="faqAccordion" key={index}> {/* 加key属性优化渲染 */}
                            <div className="accordion-item my-3">
                              <div 
                                className="accordion-title" 
                                onClick={() => {
                                  // 点击切换:当前项已展开则收起,否则展开
                                  setActiveIndex(activeIndex === index ? null : index);
                                }}
                              >
                                <div className="me-2 plus">{activeIndex === index ? "-" : "+"}</div>
                                <div>{faqe.title}</div>
                              </div>
                              {/* 仅当前项索引匹配时显示内容 */}
                              {activeIndex === index && (
                                <div className="accordion-content ps-5">{faqe.description}</div>
                              )}
                            </div>
                          </div>
                        );
                      })}
                  </div>
                </div>
              </div>
            </div>
        </React.Fragment>
    );
  }
  // 数据加载时的占位显示
  return <div>Loading...</div>;
};
export default Faq;

额外优化点:

  • 给useEffect添加空依赖数组,避免组件重复发起API请求
  • 给列表元素添加key属性,符合React渲染规范
  • 补充加载状态占位,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:07:01