React/FetchAPI: 如何通过id从相关的json中获取数据

React/FetchAPI: How to take data from related json by id

我想从 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

所以它是正确的,但是当我检查 Component Props 时,这些 props 没有被转移。

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()。但是我不知道怎么处理。

在这种情况下你需要 async await 并且使用 Promise.all 很好,因为你在 forEach 中进行 fetch。

forEach 需要 await Promise.all,fetch 需要 await。这意味着它将等到 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;
    });
 }

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

fetch api returns 一个承诺,你应该在承诺解析处理程序中设置你的状态。像这样修改你的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
            });
          });
      })
}