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

React JS中如何触发.map()渲染列表中的指定单个元素

手风琴组件单条展开问题修复

问题根源

所有渲染的列表项共用了同一个布尔类型的display状态,状态变更时所有项都会同步触发渲染逻辑,无法区分当前被点击的具体项,因此会出现全展开/全折叠的联动问题。

修复实现(单开模式:同一时间仅展开一项)

把状态从布尔值改为存储当前展开项的唯一ID,通过ID匹配判断每一项的展开状态:

import { useState } from "react";
import { AiFillPlusCircle, AiFillMinusCircle } from "react-icons/ai";
import data from "../data";

export default function Container() {
  // 存储当前展开项的id,初始为null代表默认全折叠
  const [activeId, setActiveId] = useState(null);

  const clickHandle = (id) => {
    // 点击已展开的项则折叠,否则展开当前点击项
    setActiveId(activeId === id ? null : id);
  };

  return (
    <>
      <div className="fContainer container">
        <div className="headingContainer">
          <h2 className="mainHeading">Questions And Answers About Login</h2>
        </div>

        <div className="fQuesContainer container">
          {data.map((question) => {
            const { id, title, info } = question;
            // 仅当前项id匹配激活id时为展开状态
            const isOpen = activeId === id;
            return (
              <div className="qCard" key={id}>
                <div className="qCardTitle">
                  <h4 className="qTitle">{title}</h4>
                  <button className="btnContainer" onClick={() => clickHandle(id)}>
                    {isOpen ? (
                      <AiFillMinusCircle size="2.4em" />
                    ) : (
                      <AiFillPlusCircle size="2.4em" />
                    )}
                  </button>
                </div>
                {isOpen && (
                  <>
                    <hr className="fHr" />
                    <p className="fInfo">{info}</p>
                  </>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
}

扩展:多开模式实现(支持同时展开多个项)

如果需要支持同时展开多个手风琴项,把状态改为存储已展开项的ID数组即可:

// 初始为空数组,默认全折叠
const [openIds, setOpenIds] = useState([]);

const clickHandle = (id) => {
  setOpenIds(prev => 
    prev.includes(id) 
      ? prev.filter(itemId => itemId !== id) // 已存在则移除(折叠)
      : [...prev, id] // 不存在则加入(展开)
  )
}

// 渲染时判断逻辑改为
const isOpen = openIds.includes(id);

效果参考

  • 折叠状态:
    折叠状态效果
  • 单条展开状态:
    点击+图标后的展开效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:45:56