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

React项目fetch请求异常及读取gameArray属性报错求助

问题排查与解决方案

咱们一步步拆解你的问题,先解决最核心的几个关键点:

1. 表单提交直接中断了Fetch请求(最关键的根因)

你用的是<button type="submit">,点击后浏览器会默认触发表单的提交刷新页面行为。这就导致你的fetchHaloMatches函数刚执行到fetch步骤,页面就直接刷新了——所以网络面板看不到请求、断点被跳过,都是因为页面重新加载后,之前的代码上下文直接消失了。

修复方法:在点击事件里阻止默认行为:

async fetchHaloMatches(e) {
  e.preventDefault(); // 阻止表单默认提交刷新页面
  // 剩下的原有逻辑不变
}

确保按钮的onClick正确传递事件参数:

<button type="submit" onClick={this.fetchHaloMatches}>Search</button>

2. Props传递名称不匹配,导致gameArray未定义错误

在ButtonMatches的render中,你传给MatchList的props是recentMatches={this.data},但在MatchList里却尝试访问this.props.data.gameArray——这里的props名称是recentMatches,不是data!所以this.props.data是undefined,自然无法读取gameArray。

修复方法:统一props名称即可,比如修改MatchList的代码:

// MatchList.js的render方法
return(
  <MatchEntry 
    game={this.props.recentMatches.gameArray[i]} 
    category={this.props.recentMatches.categoryArray[i]} 
    map={this.props.recentMatches.mapArray[i]} 
    victory={this.props.recentMatches.victoryArray[i]} 
    kills={this.props.recentMatches.killsArray[i]} 
    deaths={this.props.recentMatches.deathsArray[i]} 
  />
);

3. 使用实例属性this.data而非State,导致组件无法响应数据更新

你把gameArray等数据存在了实例属性this.data里,但React只会在state或props变化时触发组件重新渲染。即使fetch成功填充了this.data,组件也不会自动刷新,因为React完全不知道这些数据发生了变化。

修复方法:把这些数组移到组件的state中:

constructor(props) {
  super(props);
  this.state = { 
    totalKD: 0, 
    totalWL: 0,
    gameArray : [],
    categoryArray : [],
    mapArray : [],
    victoryArray : [],
    killsArray : [],
    deathsArray : [],
  };
  this.fetchHaloMatches = this.fetchHaloMatches.bind(this);
}

然后在fetch的回调里用this.setState更新数据:

.then(res => {
  let totalKills = 0, totalDeaths = 0, totalVictories = 0, totalLosses = 0;
  // 先创建新数组,避免直接修改state
  const gameArray = [];
  const categoryArray = [];
  const mapArray = [];
  const victoryArray = [];
  const killsArray = [];
  const deathsArray = [];

  for (let i=0; i< res.data.length; i++) {
    const match = res.data[i];
    victoryArray[i] = match.victory;
    victoryArray[i] ? totalVictories++ : totalLosses++
    killsArray[i] = match.stats.kills;
    totalKills += killsArray[i];
    deathsArray[i] = match.stats.deaths;
    totalDeaths += deathsArray[i];
    mapArray[i] = match.details.map.name;
    categoryArray[i] = match.details.category.name;
    gameArray[i] = match.details.engine.name;
  }
  const totalKD = totalKills / totalDeaths;
  const totalWL = totalVictories / totalLosses;
  this.setState({ 
    totalKD, 
    totalWL,
    gameArray,
    categoryArray,
    mapArray,
    victoryArray,
    killsArray,
    deathsArray,
  });
})

最后在render里传递state给MatchList:

<MatchList recentMatches={ this.state } />

4. 额外优化:添加加载状态与错误处理

建议在state里添加isLoading状态,避免在数据加载中渲染错误内容,同时完善fetch的错误处理:

// constructor中添加
this.state = {
  // ...其他状态
  isLoading: false,
};

// 修改fetchHaloMatches为async/await风格,更易读
async fetchHaloMatches(e) {
  e.preventDefault();
  this.setState({ isLoading: true });
  try {
    const gamertag = document.getElementById("search-recent-matches").value;
    const url3 = `https://cryptum.halodotapi.com/games/hmcc/stats/players/${gamertag}/recent-matches?page=1`;
    const response = await fetch(url3, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Cryptum-API-Version': '2.3-alpha',
        'Authorization': 'Cryptum-Token HOePLO1QYGIbelnxcQSq9y6ZXbX6MWahQZlQq1zaXQqHXEd4mWyOZ6YgaijjdCyB'
      }
    });
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }
    const res = await response.json();
    // ...处理数据并更新state
    this.setState({ isLoading: false });
  } catch (error) {
    console.log("There was an error: " + error);
    this.setState({ isLoading: false });
  }
}

然后在render里判断加载状态:

render() {
  const { totalKD, totalWL, isLoading } = this.state;
  if (isLoading) {
    return <div>加载中...</div>;
  }
  if (totalKD === 0 && totalWL === 0) {
    // 初始状态,显示表单
    return (
      <div>
        <form>
          <label htmlFor="gamertag">Xbox Live Gamertag:</label>
          <input type="search" id="search-recent-matches" name="Gamertag" placeholder="Enter a Gamertag..."></input>
          <button type="submit" onClick={ this.fetchHaloMatches } >Search</button>
        </form>
      </div>
    );
  } else {
    // 有数据,显示表单+MatchList
    return (
      <div>
        <div>
          <form>
            <label htmlFor="gamertag">Xbox Live Gamertag:</label>
            <input type="search" id="search-recent-matches" name="Gamertag" placeholder="Enter a Gamertag..."></input>
            <button type="submit" onClick={ this.fetchHaloMatches } >Search</button>
          </form>
        </div>
        <MatchList recentMatches={ this.state } />
      </div>
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:37:38