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

如何批量执行Fetch异步请求并解决React链接合并问题

问题:NFL API获取球员姓名后链接合并为一个,无法生成独立链接

我想从NFL API获取橄榄球球员姓名,将每个姓名做成跳转对应球员页面的链接,但当前所有链接被合并成一个,页面输出类似TaaotaTarlaoaortaJoshAllen的内容,而非预期的多个独立加粗链接(如<strong>Tua Tagovailoa</strong> <strong>Patrick Mahomes</strong> <strong>Joe Burrow</strong> <strong>Josh Allen</strong>)。

补充说明:API数据拉取成功,但展示格式不符合需求,需要多个独立链接。未接入API时的测试代码可正常生成多个独立链接,输出如下:

Special Team 1 Special Team 2 Special Team 3 Special Team 4

测试代码:

import { Link } from "react-router-dom"
import _navbar from "../NavBar/navbar";

export default function _specialTeamsPage() {
    const specialteams = [1, 2, 3, 4, 5];

    return (
        <>
        <_navbar />
        <div>
            {specialteams.map((specialteam) => (
                <Link key={specialteam} to={`/specialteam/${specialteam}`}>
                    Special Team {specialteam}
                </Link>
            ))}
        </div>
        </>
    );
}

接入API后出问题的代码:

import { Link } from "react-router-dom";
import _navbar from "../NavBar/navbar";
import React, { useEffect, useState } from "react";
import styles from './card.module.css';

export default function _quarterbacksPage() {
    const quarterbacks = [3139477, 4241479, 3918298, 3915511, 2577417];
    const [names, setNames] = useState([]);
    for (let i = 0; i < quarterbacks.length; i++){
        const options = {
            method: 'GET',
            headers: {
                'x-rapidapi-key': 'secret key',
                'x-rapidapi-host': 'nfl-api-data.p.rapidapi.com'
            }
        };
    
        const FullNameUrl = 'https://nfl-api-data.p.rapidapi.com/nfl-ath-fullinfo?id=' + quarterbacks[i];
        const fetchFullName = async () => {
            fetch(FullNameUrl, options)
            .then(response => response.json())
            .then(response => {
                const name = response.athlete.fullName;
                setNames([...names, ...name]);
                
            })
        };
    
        useEffect(() => {
            fetchFullName();
        }, []);
    }


    return (
        <>
            <div>
                <_navbar />
                {names.map((name) => (
                    <Link key={name} to={`/quarterback/${name}`}>
                    {name}
                    </Link>
                ))}
            </div>
        </>
    );
}

问题原因与修复方案

核心问题

  1. 数组更新逻辑错误:setNames([...names, ...name])中的...name会把字符串姓名拆分为单个字符(字符串属于可迭代对象),导致names数组存储的是单个字符而非完整姓名,后续渲染时所有字符被拼接在一起。
  2. 循环内滥用useEffect:在for循环中定义useEffect会导致重复注册副作用,且闭包问题会让每次更新都拿到初始空数组,最终数据混乱。
  3. Key值不唯一:用姓名作为Link的key,若存在重复姓名会引发React渲染异常。

修复后的代码

import { Link } from "react-router-dom";
import _navbar from "../NavBar/navbar";
import React, { useEffect, useState } from "react";
import styles from './card.module.css';

export default function _quarterbacksPage() {
    const quarterbacks = [3139477, 4241479, 3918298, 3915511, 2577417];
    const [playerData, setPlayerData] = useState([]);

    // 批量获取所有球员数据
    const fetchAllPlayers = async () => {
        const options = {
            method: 'GET',
            headers: {
                'x-rapidapi-key': 'secret key',
                'x-rapidapi-host': 'nfl-api-data.p.rapidapi.com'
            }
        };

        // 并行发起所有API请求
        const requests = quarterbacks.map(id => 
            fetch(`https://nfl-api-data.p.rapidapi.com/nfl-ath-fullinfo?id=${id}`, options)
                .then(res => res.json())
                .then(data => ({
                    id,
                    name: data.athlete.fullName
                }))
        );

        const results = await Promise.all(requests);
        setPlayerData(results);
    };

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

    return (
        <>
            <div>
                <_navbar />
                {playerData.map((player) => (
                    <Link 
                        key={player.id} 
                        to={`/quarterback/${player.name}`}
                        style={{ fontWeight: "bold", marginRight: "10px" }}
                    >
                        {player.name}
                    </Link>
                ))}
            </div>
        </>
    );
}

修复要点

  • 正确更新数组:用[...names, name]替代[...names, ...name],将完整姓名作为数组元素添加,避免拆分字符。
  • 统一管理副作用:将所有请求逻辑放入单个useEffect,使用Promise.all并行处理多请求,提升效率同时避免重复注册。
  • 使用唯一Key:以球员ID作为Link的key,保证唯一性,避免渲染异常。
  • 添加加粗样式:通过内联样式或CSS类实现姓名加粗效果,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:47:06