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

React点击按钮无法更新map渲染元素的className,求修复方案

React FAQ组件状态更新不触发渲染的修复方案

问题根源

你直接修改了Open数组内的元素(比如items[3]=true这类操作),但React的状态更新依赖新的引用——直接修改原数组/对象属于可变操作,React无法检测到状态变化,自然不会触发重渲染,导致外层div的className无法更新。


修复思路及代码调整

1. 必须通过setOpen生成新数组更新状态

永远不要直接修改state中的数组或对象,要先创建副本修改,再通过setOpen传递新引用触发重渲染。

2. 重构点击事件逻辑

合并开关逻辑,通过索引定位要修改的项,用函数式更新确保拿到最新状态:

const toggleItem = (index) => {
  setOpen(prevOpen => {
    // 复制原数组,避免修改原状态
    const updatedItems = [...prevOpen];
    // 复制要修改的项,保证数据不可变
    const updatedItem = { ...updatedItems[index] };
    // 切换开关状态
    updatedItem.isOpen = !updatedItem.isOpen;
    updatedItem.buttonClass = updatedItem.isOpen ? "faq-button open" : "faq-button close";
    updatedItems[index] = updatedItem;
    return updatedItems;
  });
}

3. 优化数据结构(推荐)

别用数组索引(items[3]、items[4])存储状态,改成对象属性可读性更强,比如Open数组的每一项应该是:

{
  id: 1,
  question: "你的问题内容",
  answer: "对应的答案",
  isOpen: false,
  buttonClass: "faq-button close"
}

修改后的完整代码

import '../Homepage/Body.css';
import './FAQ.CSS';
import React, { useEffect, useState } from 'react';
import InfoForPatPage from "./Informace";

function FaqPage(props) {
  const [Open, setOpen] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState("");

  useEffect(() => {
    loadAsyncData();
  }, []);

  const toggleItem = (index) => {
    setOpen(prevOpen => {
      const updatedItems = [...prevOpen];
      const updatedItem = { ...updatedItems[index] };
      updatedItem.isOpen = !updatedItem.isOpen;
      updatedItem.buttonClass = updatedItem.isOpen ? "faq-button open" : "faq-button close";
      updatedItems[index] = updatedItem;
      return updatedItems;
    });
  }

  return (
    <div className="page">
      <InfoForPatPage />
      <div className="faq-container">
        <h2>FAQ</h2>
        {Open.map((item, index) => (
          <div className={item.isOpen ? "a" : "b"} key={item.id}>
            <button 
              onClick={() => toggleItem(index)} 
              id={item.id} 
              className={item.isOpen ? 'active' : ''}
            >
              <p className="faq-button-text">{item.question}</p>
            </button>
            <div className="panel fade-in-top">
              <p>{item.answer}</p>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 00:36:28