从API获取数据我正在获取此类数据:
0: {name: "bulbasaur", url: "https://pokeapi.co/api/v2/pokemon-species/1/"}
1: {name: "ivysaur", url: "https://pokeapi.co/api/v2/pokemon- species/2/"}
2: {name: "venusaur", url: "https://pokeapi.co/api/v2/pokemon-species/3/"}
3: {name: "charmander", url: "https://pokeapi.co/api/v2/pokemon-species/4/"}
4: {name: "charmeleon", url: "https://pokeapi.co/api/v2/pokemon-species/5/"}
5: {name: "charizard", url: "https://pokeapi.co/api/v2/pokemon-species/6/"}
为了获得更详细的信息,我需要获取每个URL。我正在尝试使用Promise.all并更新状态,但是代码不起作用:
class App extends Component {
constructor(props){
super(props);
this.state = {
pokemons: [],
names: [],
isLoaded: false
};
}
componentDidMount(){
this.loadPokemons();
this.loadPokemonAdditionalInfo();
}
loadPokemons(){
fetch('https://pokeapi.co/api/v2/pokemon-species')
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
names: json.results
})
})
}
loadPokemonAdditionalInfo(){
Promise.all(this.state.names.map(name =>
fetch(name.url)
.then(results => results.forEach(result => result.json())
.then(r => {
this.setState({
pokemons: [...this.state.pokemons, r]
})
}
))))
}
请告知我我做错了。
答案 0 :(得分:1)
您的问题是,在安装组件后,您将同时调用loadPokemons和loadPokemonAdditionalInfo。您需要等到获取了神奇宝贝的名字,然后才能获取它们的其他信息。
this.loadPokemonAdditionalInfo()
应该从
this.setState({
isLoaded: true,
names: json.results
}, this.loadPokemonAdditionalInfo)
答案 1 :(得分:0)
Promise.all应该具有array或promises,所以参数应该是fetches的数组。
Promise.all(this.state.names.map(name =>
fetch(name.url)))
.then(results => results.forEach(result => result.json())
.then(r => {
this.setState({
pokemons: [...this.state.pokemons, r]
})
})
答案 2 :(得分:0)
首先,当您尝试加载其他数据时,名称还没有完成。
只需使您的componentDidMount
函数异步并等待每个调用(还要确保您为每个调用都返回一个诺言)。
async componentDidMount(){
await this.loadPokemons();
await this.loadPokemonAdditionalInfo();
}
您还返回结果的迭代,而不是每个结果json的数组。
将results.forEach(result => result.json())
替换为:
results.map(result => result.json())
在loadPokemonAdditionalInfo
const results = [{ name:'John' }, { name:'Jane' }];
console.log('forEach', results.forEach(result => result.name));
console.log('map', results.map(result => result.name));
答案 3 :(得分:0)
不能同时运行
this.loadPokemons();
this.loadPokemonAdditionalInfo();
以同步方式,setState需要一些时间来更改状态。这就是为什么要对setState进行回调的原因。
以下应该有效:
loadPokemons(){
fetch('https://pokeapi.co/api/v2/pokemon-species')
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
names: json.results
}, () => {
this.loadPokemonAdditionalInfo()
})
})
}
loadPokemonAdditionalInfo() {
const { names } = this.state;
const promises = names.map(
name => fetch(name.url).then(response => response.json())
)
Promise.all(promises).then(results => {
this.setState({
pokemons: [...this.state.pokemons, ...results]
})
})
}
componentDidMount(){
this.loadPokemons();
}