如何在React中使用reduce和promise.all显示多组数据

时间:2019-05-09 12:31:35

标签: javascript reactjs

我正在通过API进行两次调用。我想显示播放电视节目和电视节目的最佳结果。我有两个API调用都返回的所有数据,但是我的代码效率不高。我想以某种方式获取返回的数据,并将其显示在单个组件(TopAnime)中,然后将其映射并返回提供的信息。

我认为减少将是最好的方法,但是我现在很困惑。我的想法是将API返回的数据减少到一个数组中。将该简化后的数组作为我的新状态传递,然后让我的组件显示它而不必编写重复的代码。因为我已经两次编写了该组件,所以同时显示了topTv和topAIring,但是重复代码显然不是最佳实践。

6

1 个答案:

答案 0 :(得分:0)

由于来自API的响应包含一个名为rank的标志,因此可以使用Array.prototype.filter仅显示1-6的节目。

Working demo here

import React, { Component } from "react";
import { TopAnime } from "./TopAnime";

export class HomePage extends Component {
  state = {
    topTv: [],
    topAiring: []
  };

  async getData() {
    const api = "https://api.jikan.moe/v3";
    const urls = [`${api}/top/anime/1/tv`, `${api}/top/anime/1/airing`];

    return Promise.all(
      urls.map(async url => {
        return await fetch(url); // fetch data from urls
      })
    )
      .then((
        responses // convert response to json and setState to retrieved data
      ) =>
        Promise.all(responses.map(resp => resp.json())).then(data => {
          // if you care about mutation use this
          const topTvFiltered = data[0].top.filter( (item) => item.rank <= 6 );
          const topAiringFiltered = data[1].top.filter( (item) => item.rank <= 6 );

          this.setState({
            topTv: topTvFiltered,
            topAiring: topAiringFiltered
          });
        })
      )
      .catch(err => console.log("There was an error:" + err));
  }

  componentDidMount() {
    this.getData();
  }

  render() {
    const { topTv, topAiring } = this.state;
    return (
      <React.Fragment>
        { topTv.length > 0 ? <h2>Top TV</h2> : null }
        {this.state.topTv.map((item, index) => (
          <TopAnime key={index} title={item.title} image={item.image_url} />
        ))}
        { topAiring.length > 0 ? <h2>Top airing</h2> : null }
        {this.state.topAiring.map((item, index) => (
          <TopAnime key={index} title={item.title} image={item.image_url} />
        ))}
      </React.Fragment>
    );
  }
}