React / FetchAPI:如何通过id

时间:2019-01-19 16:10:12

标签: javascript reactjs fetch-api

我想从JSON中获取数据,然后通过ID从相关JSON中获取另一数据,并将其推送到状态数组movies

这是我的代码:

state = {
    movies: []
}

componentDidMount() {

    fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
        .then(response => response.json())
        .then(data => {
            const movies = data.results;

            movies.forEach(movie => this.moviePageAndGenres(movie.id, movie));

            this.setState({
                movies
            });
        })
}

moviePageAndGenres = (id, element) => {
    fetch('https://api.themoviedb.org/3/movie/' + id + '?api_key=APIKEY')
        .then(response => response.json())
        .then(data => {
            element.genres = data.genres;
            element.homepage = data.homepage;
        });
}

render()中,我只是console.log我的movies检查其中的数据是否正确。

输出: image

这是正确的,但是当我检查“组件道具”时,这些道具没有被转移。

image

这是我转移道具的方式:

const movies = this.state.movies.map(movie =>
 <Movie genres={movie.genres}
        homepage={movie.homepage}
        key={movie.id}
        title={movie.title}
        poster={movie.poster_path}
        rating={movie.vote_average}
 />
)

我想这是异步调用fetch()的多次调用所引起的问题。但是我不知道如何处理。

2 个答案:

答案 0 :(得分:1)

在这种情况下,您需要异步等待,最好使用Promise.all,因为您要在forEach中进行抓取。

对于ForEach,您需要等待Promise.all,而对于fetch,则需要等待。这意味着它将等到forEach完成

更改

    fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
    .then(response => response.json())
    .then(data => {
        const movies = data.results;

        movies.forEach(movie => this.moviePageAndGenres(movie.id, movie));

        this.setState({
            movies
        });
    })

收件人

  fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
    .then(response => response.json())
    .then(async data => {
        const movies = data.results;
        await Promise.all(movies.forEach(async movie => await this.moviePageAndGenres(movie.id, movie)))

        this.setState({
            movies
        });
    })

更改

  moviePageAndGenres = (id, element) => {
      fetch('https://api.themoviedb.org/3/movie/' + id + '?api_key=APIKEY')
    .then(response => response.json())
    .then(data => {
        element.genres = data.genres;
        element.homepage = data.homepage;
    });
 }

收件人

   moviePageAndGenres = async (id, element) => {
      return await fetch('https://api.themoviedb.org/3/movie/' + id + '?api_key=APIKEY')
    .then(response => response.json())
    .then(data => {
        element.genres = data.genres;
        element.homepage = data.homepage;
    });
 }

答案 1 :(得分:1)

其不起作用的原因是,您正在触发多个异步的访存调用,并在其后立即设置状态。在这种情况下,setState将获得空电影。

fetch api返回一个promise,您应该在promise resolution处理程序中设置状态。像这样修改componentDidMount

componentDidMount() {

  fetch('https://api.themoviedb.org/3/movie/popular?api_key=APIKEY&page=1')
      .then(response => response.json())
      .then(data => {
          const movies = data.results;
          Promise.all(movies.map(movie => fetch(
            `https://api.themoviedb.org/3/movie/${movie.id}?api_key=APIKEY`
          )))
          .then(resp => Promise.all( resp.map(r => r.json()) ))
          .then(result => {
            const movies = result.map((data, i) => {
              const movie = Object.assign(movies[i], {
                genres: data.genres,
                homepage: data.homepage
              });
              return movie;
            });
            this.setState({
              movies
            });
          });
      })
}