Javascript 在React after Async函数中从数组渲染对象

Javascript 在React after Async函数中从数组渲染对象,javascript,reactjs,Javascript,Reactjs,我的状态中有一个数组data,其中包含一组对象,但是当我尝试访问和呈现存储在对象中的某些信息时,页面上不会出现任何预期的文本 我的当前代码位于我的渲染函数中,如下所示: <ul> {this.state.data.map(match => <Link to={'teams/'+ team.homeId} key={match.id}><li>{match.homeTeam}</li></Link> <ul&g

我的状态中有一个数组
data
,其中包含一组对象,但是当我尝试访问和呈现存储在对象中的某些信息时,页面上不会出现任何预期的文本

我的当前代码位于我的渲染函数中,如下所示:

<ul>
    {this.state.data.map(match =>
    <Link to={'teams/'+ team.homeId} key={match.id}><li>{match.homeTeam}</li></Link>
<ul>

您需要检查数据是否已成功检索,如下所示:

<ul>
{this.state.data && this.state.data.map(match => {
return (<Link to={'teams/'+ team.homeId} key={match.id}>{match.homeTeam}</Link>)
}
 <ul>
    {this.state.data&&this.state.data.map(匹配=>{ 返回({match.homeTeam}) }

您需要实际等待请求完成

您正在底部执行
this.setState({data:[…this.state.data,…matchInfo]})
操作,但您正在异步更改
matchInfo
对象,因此
setState
在所有axios请求完成之前发生。更改状态不会导致重新渲染,只会通过
setState
进行设置

如果您等待所有axios调用,并在调用
setState
之前构建对象,您将得到您想要的:

async componentDidMount() {
  const soccerApi = axios.create({
    baseURL: 'https://soccer.sportmonks.com/api/v2.0',
    params: { api_token: API }
  });
  const res = await soccerApi.get(`/livescores`);
  const matchInfo = await Promise.all(res.data.data.map(async row => {
    const [homeTeamInfo, awayTeamInfo, leagueInfo] = await Promise.all([
      soccerApi.get(`/teams/${row.localteam_id}`),
      soccerApi.get(`/teams/${row.visitorteam_id}`),
      soccerApi.get(`/leagues/${row.league_id}`)
    ]);
    return { 
      id: row.id,
      homeScore: row.scores.localteam_score,
      awayScore: row.scores.visitorteam_score,
      homeId: homeTeamInfo.data.data.id,
      homeTeam: homeTeamInfo.data.data.name,
      awayId: awayTeamInfo.data.data.id,
      awayTeam: awayTeamInfo.data.data.name,
      leagueName: leagueInfo.data.data.name
    };
  }));
  this.setState({
    data: [...this.state.data, ...matchInfo]
  });
}

主要问题是您在forEach中调用axios。您没有等待它们。您是在forEach中调用它们,而不是等待

所以你需要这样做

const allPromises = res.data.data.map((id, i) => { return axios.get() } 

// then 

const allResponseValues = await axios.all(allPromises).catch(console.error)

// do something with allResponses and update matchInfo

// finally
this.setState({...})
为了可读性和清晰度,还将渲染功能更新到下面

            {this.state.data.map(match => (
              <Link to={"teams/" + match.homeId} key={match.id}>
                <li>{match.homeTeam}</li>
              </Link>
            ))}

{this.state.data.map(匹配=>(
  • {match.homeTeam}
  • ))}
    您是以数组还是对象的形式获取数据?
    .map
    仅适用于array@MonteCristo
    this.state.data
    是一个对象数组。您能用完整的组件代码更新问题吗?@MonteCristo当然,请稍等。@MonteCristo就到了。当我运行console.log时,这也无法显示任何数据
    this.state.data
    使用我页面上的一个按钮,数组已满。我认为
    }
    最后也丢失了。但不确定在平衡后从IDE复制到So时是否键入:
    .map(match=>{return(…)})}
    它仍然没有在页面上输出任何内容,但我真的不确定这一点出了什么问题,谢谢。通过在我的页面中设置一个简单的按钮console.log
    this.state.data
    来验证
    this.state.data
    中包含的信息是否确实填充了
    matchInfo
    中的信息,这可能是我的错误理解你的解释吗?@Tigerr107:你可能会在控制台中看到数据,因为你的代码正在改变对象,但是你在改变对象之前调用了
    setState
    。React不会检测你是否改变了对象,也不会重新渲染;这就是为什么强烈鼓励不可变性。最好只执行一次setState您实际上拥有数据,或者如果希望随着数据的更改而增量渲染,则需要定期调用setState。
                {this.state.data.map(match => (
                  <Link to={"teams/" + match.homeId} key={match.id}>
                    <li>{match.homeTeam}</li>
                  </Link>
                ))}