我想从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
这是正确的,但是当我检查“组件道具”时,这些道具没有被转移。
这是我转移道具的方式:
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()
的多次调用所引起的问题。但是我不知道如何处理。
答案 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
});
});
})
}