如何从几个API调用中正确获取数据并将其显示到React中的DOM

时间:2019-05-08 13:05:35

标签: javascript reactjs

我有一个组件,可以显示特定API调用的最高结果。我的问题是如何正确有效地进行几个API调用并显示它们。我目前从两个电话开始,分别是顶级电视和顶级直播。

我意识到我的初始状态仅包含一个空数组,并且我想返回的每个特定结果都需要一个额外的数组,但是我目前陷入困境。我尝试使用async等待来获得一个结果,但是调用多个时却失败了。

class HomePage extends Component {
  state = {
    topTv: []
  }

componentDidMount() {
    const api = 'https://api.jikan.moe/v3'
    const urls = [
      fetch(`${api}/top/anime/1/tv`),
      fetch(`${api}/top/anime/1/airing`)
    ]

    Promise.all(urls)
      .then(res => Promise.all(res.map(r => r.json())))
      .then(data => this.setState = ({
        topTv: data
      }))
      .catch(err => console.log('There was an error:' + err))
  }

  render() {
    return (
      <HomeWrapper>
        <h2>Top anime</h2>
        <TopAnime>
          {this.state.topTv.map((ani) => {
            return (
              <div key={ani.mal_id}>
                <img src={ani.image_url} alt='anime poster' />
                <h3>{ani.title}</h3>
              </div>
            )
          }).splice(0, 6)}
        </TopAnime>
      </HomeWrapper>
    )
  }
}

2 个答案:

答案 0 :(得分:0)

当前尝试的问题只是您使用setState的方式。 它是一个函数,而不是您要设置的变量。

this.setState = ({
    topTv: data
}))

应该是

this.setState({
    topTv: data
}))

此外,您可能希望合并数据中的实际数组,然后合并setState。

 const results = [...data[0].top, ...data[1].top];
 this.setState({
    topTv: results
 }))

请注意,Promise.all可以正常工作。但是,如果您要查找 async await 示例,我创建了一个sandbox

请确保urls只是字符串数组,而不是用fetch包装。

干杯!

答案 1 :(得分:0)

您可以使用如下创建的asyncawait fetchJson函数替换fetch。

async function fetchJson(url){
return new Promise((resolve,reject)=>{
    try{
        var resp = await fetch(url)
        data = await resp.json();
        resolve(data);
    }catch(e){
        //reject or do something else with the error
    }
}) }

您可以使用它来获取多个呼叫,如下所示。

const urls = [
fetch(`${api}/top/anime/1/tv`),
fetch(`${api}/top/anime/1/airing`)]

Promise.all(urls).then(responseArr=>{
    //do something with the array
}).catch(err=>{/*do something with error*/})

我认为编写一个为我处理嵌套回调或promise链的函数要容易得多,因此我不必每次都去打扰。这样也没有性能差异或瀑布效应。

在指定每个调用时,您需要使用

这样的url数组。
[{url:'myApiUrl', functionOrKey: ''}]

然后,您可以将responseArr与索引值进行映射,并通过index到达其状态键,或者将数据传递给其相应的函数。