首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React -如何在多次api调用后等待UI更新?

React -如何在多次api调用后等待UI更新?
EN

Stack Overflow用户
提问于 2021-05-14 22:13:11
回答 2查看 71关注 0票数 0

我是个新手,需要一些帮助。

我已经创建了一个Pokedex,应用程序从API调用中生成数据,但它需要进行另一个API调用来获取更多数据,然后再执行相同的过程。

在我的例子中,用户需要按下按钮三次才能生成“完整”信息。

我是否需要使用React中实现的"useEffect“钩子来解决这个问题?如果需要,如何解决?

当前代码:

代码语言:javascript
复制
    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。

提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2021-05-15 23:36:14

代码语言:javascript
复制
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
          });
        });
      });
    });
  };

用这个替换你的搜索功能,它会运行的很好。

票数 0
EN

Stack Overflow用户

发布于 2021-05-18 01:21:39

这是您调用函数的模式

代码语言:javascript
复制
api.get().then(res1 => {
   setPokemon({...})
   api.get(pokemon.id).then(res2 => {
     set...
   })
})

你的代码的问题是,你假设一旦你的setPokemon结束,口袋妖怪就会有这个值,所以你就调用它,但是,这不是它的工作方式。现在只需要知道,在函数完全执行之后,pokemon状态将具有它的值。如果您想进一步了解它是如何工作的,请从这里开始https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=4s

现在我所做的就是获取已经存在于该块中的响应,并从响应中传递id。

代码语言:javascript
复制
api.get().then(res1 => {
   setPokemon({...}) // res1 is available here
   api.get(res1.data.id).then(res2 => {
     set... // res2 is available here
   })
})

同样做同样的事情也有多种方式。所以继续学习吧。我还更改了您的单个状态的代码,这样您就不必每次都调用setState。

代码语言:javascript
复制
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。谢谢!!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67535818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档