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

React中如何通过双API请求匹配ID实现排名列表展示?

问题描述

我需要调用两个不同的API获取数据:

  • API #1:获取未按排名排序的玩家姓名(关联玩家ID)
  • API #2:获取按排名排序的玩家ID、排名位置及分数,需要通过匹配ID来获取对应玩家的姓名。

我曾用原生JS异步函数实现过类似逻辑:

<script>
    getData();

    async function getData() {
        const response = await fetch('http://localhost:3008/api/highscore/players')
        console.log(response);
        const data = await response.json();
        const req = await fetch('http://localhost:3008/api/players')
        console.log(req);
        const info = await req.json();
        length = data.players.length;
        console.log(data);
        var temp = "";
        for (i = 0; i < length; i++)
            for (j = 0; j < length; j++)  {
                {
                    if (info.players[i].id == data.players[j].id) {
                        temp += "<tr>";
                        temp += "<td>" + data.players[j].position + "</td>";
                        temp += "<td>" + info.players[i].name + "</td>";
                        temp += "<td>" + data.players[j].score + "</td>";
                        temp += "</tr>";
                    }
                }
            }
        document.getElementById("data").innerHTML = temp;
    }
</script>

以下是我的React项目代码,需要在此实现该逻辑,请问该如何实现?

import axios from "axios";
import React, { useState, useEffect } from "react";

const Ranking = () => {
  const [playerName, setPlayerName] = useState([]);
  const [playerRank, setPlayerRank] = useState([]);

  const fetchData = () => {
    const playerAPI = 'http://localhost:3008/api/players';
    const playerRankAPI = 'http://localhost:3008/api/highscore/players';

    const getINFOPlayer = axios.get(playerAPI)
    const getPlayerRank = axios.get(playerRankAPI)
    axios.all([getINFOPlayer, getPlayerRank]).then(
      axios.spread((...allData) => {
        const allDataPlayer = allData[0].data.players
        const getINFOPlayerRank = allData[1].data.players

        setPlayerName(allDataPlayer)
        setPlayerRank(getINFOPlayerRank)
      })
    )
  }
  
  useEffect(() => {
    fetchData()
  }, [])

  return (
    <table className="table table-bordered">
      <tr>
        <th>Rank</th>
        <th>Name</th>
        <th>Points</th>
      </tr>
        <tbody>
          {playerName?.map((name) => {
            return (
              <tr key={name.name}>
                <td>{name.name}</td>
              </tr>
            )
          })}
        </tbody>
    </table>
  )
}

export default Ranking

实现思路与代码修改

优化方向

  1. 将玩家姓名数据转为ID映射对象,替代嵌套循环,把时间复杂度从O(n²)降到O(n),提升性能
  2. 基于API2返回的已排序排名数据渲染表格,保证排名顺序正确
  3. 修复React中需用className替代class的语法问题

修改后的完整代码

import axios from "axios";
import React, { useState, useEffect } from "react";

const Ranking = () => {
  const [playerMap, setPlayerMap] = useState({});
  const [rankedPlayers, setRankedPlayers] = useState([]);

  const fetchData = () => {
    const playerAPI = 'http://localhost:3008/api/players';
    const playerRankAPI = 'http://localhost:3008/api/highscore/players';

    axios.all([axios.get(playerAPI), axios.get(playerRankAPI)])
      .then(axios.spread((playerRes, rankRes) => {
        // 把玩家数组转为{id: 玩家对象}的映射,快速通过ID查找姓名
        const nameMap = playerRes.data.players.reduce((map, player) => {
          map[player.id] = player;
          return map;
        }, {});
        setPlayerMap(nameMap);
        // 直接保存已排序的排名数据
        setRankedPlayers(rankRes.data.players);
      }))
      .catch(err => console.error('数据请求失败:', err));
  }
  
  useEffect(() => {
    fetchData();
  }, []);

  return (
    <table className="table table-bordered">
      <thead>
        <tr>
          <th>Rank</th>
          <th>Name</th>
          <th>Points</th>
        </tr>
      </thead>
      <tbody>
        {/* 遍历已排序的排名数据,保证顺序正确 */}
        {rankedPlayers?.map((rankItem) => {
          const player = playerMap[rankItem.id];
          // 处理ID不匹配的容错情况
          if (!player) return null;
          return (
            <tr key={rankItem.id}>
              <td>{rankItem.position}</td>
              <td>{player.name}</td>
              <td>{rankItem.score}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

export default Ranking;

关键逻辑说明

  • 映射对象优化:通过reduce将API1的玩家数组转换为以ID为键的对象,后续通过ID直接查找对应玩家,比嵌套循环效率更高
  • 按排名顺序渲染:直接遍历API2返回的已排序数据,确保表格展示的排名顺序正确
  • 容错处理:增加if (!player) return null的判断,避免ID不匹配时渲染错误内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:35:24