我是个新手,需要一些帮助。
我已经创建了一个Pokedex,应用程序从API调用中生成数据,但它需要进行另一个API调用来获取更多数据,然后再执行相同的过程。
在我的例子中,用户需要按下按钮三次才能生成“完整”信息。
我是否需要使用React中实现的"useEffect“钩子来解决这个问题?如果需要,如何解决?
当前代码:
import Axios from "axios";
import React, { useState } from "react";
function PK() {
const api = Axios.create({
baseURL: "https://pokeapi.co/api/v2/",
});
const [pokemon, setPokemon] = useState({});
const [pokemonDescription, fetchDescription] = useState({});
const [evolution, pokemonEvolution] = useState({});
const searchPokemon = () => {
api.get(`pokemon/magnemite`).then((response) => {
setPokemon({
name: response.data.name,
height: response.data.height,
weight: response.data.weight,
img: response.data.sprites.front_default,
id: response.data.id,
type: response.data.types[0].type.name,
type2: response.data.types[1].type.name,
});
api.get(`pokemon-species/${pokemon.id}/`).then((response) => {
console.log(response.data.evolution_chain);
fetchDescription({
entry: response.data.flavor_text_entries[0].flavor_text,
evolution: response.data.evolution_chain.url,
});
api.get(`${pokemonDescription.evolution}`).then((response) => {
console.log(response.data.chain.evolves_to[0].species.name);
pokemonEvolution({
evolution: response.data.chain.evolves_to[0].species.name,
});
});
});
});
};
return (
<div>
<h1 style={{ textTransform: "capitalize" }}>{pokemon.name}</h1>
<h1>#{pokemon.id}</h1>
<h1>{pokemon.weight / 10} Kg</h1>
<h1>{pokemon.height * 10} Cm</h1>
<img src={pokemon.img} alt="" />
<h1 style={{ textTransform: "capitalize" }}>
Type: {pokemon.type} {pokemon.type2}
</h1>
<h2 style={{ textTransform: "capitalize" }}>
{pokemonDescription.entry}
</h2>
<h1 style={{ textTransform: "capitalize" }}>
Evolution: {evolution.evolution}
</h1>
<button onClick={searchPokemon}>Click me</button>
</div>
);
}
export default PK;第一次点击:

第二次单击:

第三次点击:

因此,我不知道如何创建一个好的解决方案来同时进行调用,或者在所有调用完成后更新UI。
提前谢谢。
发布于 2021-05-15 23:36:14
const searchPokemon = () => {
api.get(`pokemon/magnemite`).then((response) => {
setPokemon({
name: response.data.name,
height: response.data.height,
weight: response.data.weight,
img: response.data.sprites.front_default,
id: response.data.id,
type: response.data.types[0].type.name,
type2: response.data.types[1].type.name
});
api.get(`pokemon-species/${response.data.id}/`).then((response) => {
fetchDescription({
entry: response.data.flavor_text_entries[0].flavor_text,
evolution: response.data.evolution_chain.url
});
api.get(`${response.data.evolution_chain.url}`).then((response) => {
pokemonEvolution({
evolution: response.data.chain.evolves_to[0].species.name
});
});
});
});
};用这个替换你的搜索功能,它会运行的很好。
发布于 2021-05-18 01:21:39
这是您调用函数的模式
api.get().then(res1 => {
setPokemon({...})
api.get(pokemon.id).then(res2 => {
set...
})
})你的代码的问题是,你假设一旦你的setPokemon结束,口袋妖怪就会有这个值,所以你就调用它,但是,这不是它的工作方式。现在只需要知道,在函数完全执行之后,pokemon状态将具有它的值。如果您想进一步了解它是如何工作的,请从这里开始https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=4s
现在我所做的就是获取已经存在于该块中的响应,并从响应中传递id。
api.get().then(res1 => {
setPokemon({...}) // res1 is available here
api.get(res1.data.id).then(res2 => {
set... // res2 is available here
})
})同样做同样的事情也有多种方式。所以继续学习吧。我还更改了您的单个状态的代码,这样您就不必每次都调用setState。
const [pokemon, setPokemon] = useState({});
const searchPokemon = async () => {
let data = []
await api.get(`pokemon/magnemite`).then(async (response) => {
data.push({
name: response.data.name,
height: response.data.height,
weight: response.data.weight,
img: response.data.sprites.front_default,
id: response.data.id,
type: response.data.types[0].type.name,
type2: response.data.types[1].type.name
});
await api.get(`pokemon-species/${response.data.id}/`).then(async (response) => {
data.push({
entry: response.data.flavor_text_entries[0].flavor_text,
});
await api
.get(`${response.data.evolution_chain.url}`)
.then((response) => {
data.push({
evolution: response.data.chain.evolves_to[0].species.name
});
});
});
});
data.map((item) => setPokemon(prev => ({...prev, ...item})))
}
return (
<div>
<h1 style={{ textTransform: "capitalize" }}>{pokemon.name}</h1>
<h1>#{pokemon.id}</h1>
<h1>{pokemon.weight / 10} Kg</h1>
<h1>{pokemon.height * 10} Cm</h1>
<img src={pokemon.img} alt="" />
<h1 style={{ textTransform: "capitalize" }}>
Type: {pokemon.type} {pokemon.type2}
</h1>
<h2 style={{ textTransform: "capitalize" }}>
{pokemon.entry}
</h2>
<h1 style={{ textTransform: "capitalize" }}>
Evolution: {pokemon.evolution}
</h1>
<button onClick={searchPokemon}>Click me</button>
</div>
);如果你喜欢这个答案,请起立投票。它只是为了堆栈溢出XD。谢谢!!
https://stackoverflow.com/questions/67535818
复制相似问题