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

React中如何在map函数中控制单个元素状态,实现多Tab独立展开

实现多Tab独立展开/收起的解决方案

你的问题根源在于所有Tab共用了同一个isOpen布尔状态,点击任意Tab时,这个全局状态会同时控制所有内容的显示/隐藏。要实现多Tab独立开关,需要为每个Tab单独维护展开状态,以下是具体实现方案:

核心思路

将单个布尔状态isOpen替换为记录每个Tab展开状态的对象(或Set集合),通过Tab的唯一标识(这里用item.id)区分不同Tab的状态。

修改后的代码

import React, { useEffect, useState } from 'react'
import axios from 'axios';
import LeaguesStyle from '../components/styles/LeaguesStyle.css';

const Leagues = () => {
  const [teamz, setTeams] = useState([]);
  const [loading, setLoading] = useState(false)
  // 用对象存储每个Tab的展开状态,key为team的id,value为布尔值
  const [openTabs, setOpenTabs] = useState({});

  const getTeams = async () => {
    try {
      const res = await axios.get('https://api-football-standings.azharimm.site/leagues');
      setTeams(res.data.data)
      setLoading(true);
    } catch (err) {
      alert(err.message)
    }
  }

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

  // 切换指定Tab的展开状态
  const toggleTab = (id) => {
    setOpenTabs(prevState => ({
      ...prevState,
      [id]: !prevState[id] // 反转当前Tab的状态
    }))
  }

  return (
    <div className="leagues">
      {loading &&
        teamz.map(item => (
          <div className='teamCard' key={item.id}>
            <div onClick={() => toggleTab(item.id)} className="teamDiv">
              <img src={item.logos.dark} className='teamLogo' />
              <h1>{item.name}</h1>
            </div>
            {/* 根据当前Tab的id判断是否显示内容 */}
            {openTabs[item.id] && <div className='card-content-active'>{item.abbr}</div>}
          </div>
        ))}
    </div>
  );
}

关键修改点说明

  • 状态结构调整:把isOpen: boolean改成openTabs: { [id: string]: boolean },每个Tab的id对应一个独立的展开状态。
  • 点击事件优化:新增toggleTab函数,通过函数式更新状态,确保基于最新状态修改,避免状态覆盖问题。
  • 内容渲染判断:不再依赖全局的isOpen,而是检查openTabs[item.id]的值决定是否显示当前Tab内容。

可选方案:使用Set集合

如果觉得对象结构不够直观,也可以用Set存储已展开的Tab id:

const [openTabIds, setOpenTabIds] = useState(new Set());

const toggleTab = (id) => {
  setOpenTabIds(prevSet => {
    const newSet = new Set(prevSet);
    newSet.has(id) ? newSet.delete(id) : newSet.add(id);
    return newSet;
  })
}

// 渲染时判断
{openTabIds.has(item.id) && <div className='card-content-active'>{item.abbr}</div>}

这种方案逻辑更清晰,适合只需要记录“是否展开”的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:15:45