reactjs 我的状态元素(口袋妖怪)使用Axios以混合顺序渲染

jxct1oxe  于 2023-05-17  发布在  React
关注(0)|答案(1)|浏览(115)

抱歉,我希望这不是个愚蠢的问题-
我试图通过制作一个小的Pokedex应用程序来更熟悉React和typescript,然而,我似乎不明白为什么在我最初加载页面后,几次刷新后,一些项目完全乱了序-我的一部分认为这是一个抓取问题,两个调用在彼此之上工作,但我不确定如何继续?
我在下面提供了我的代码:

import { useEffect, useState } from "react";
import "./App.css";
import axios from "axios";
import { PokemonType } from "./models/pokemonType";
import Pokemon from "./components/Pokemon";

function App() {
  const [pokedex, setPokedex] = useState<PokemonType[] | []>([]);
  const limit = 151;

  const axiosInstance = axios.create({
    baseURL: "https://pokeapi.co/api/v2/",
  });

  useEffect(() => {
    collectPokemon(limit);
  }, []);

  const collectPokemon = async (limit: number) => {
    axiosInstance.get(`pokemon?limit=${limit}`).then((res) => {
      const data = res.data.results;

      Promise.all(data).then((results) => {
        results.map((pkmn) => {
          mapPokemon(pkmn.name);
        });
      });
    });
  };

  const mapPokemon = async (name: string) => {
    axiosInstance.get(`pokemon/${name}`).then((res) => {
      const data: PokemonType = res.data;
      setPokedex((currentList) => [...currentList, data]);
    });
  };

  console.log(pokedex);

  return (
    <>
      <h1>Pokédex App</h1>
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-10 m-10">
        {pokedex.map((mon: PokemonType) => (
          <Pokemon key={mon.id} name={mon.name} id={mon.id} types={mon.types} />
        ))}
      </div>
    </>
  );
}

export default App;

口袋妖怪.tsx

import { PokemonType } from "../models/pokemonType";

const Pokemon = (props: PokemonType) => {
  const { name, id, types } = props;
  const paddedIndex = ("000" + (id ? id : id)).slice(-3);

  return (
    <div className="bg-gray-600 rounded-2xl p-2 transform h-180 min-w-250 transition duration-500 hover:scale-180 hover:drop-shadow-[0_10px_10px_rgba(0,0,0,.5)] border-gray-950 border-4 overflow-clip">
      <div className="bg-gray-900 text-white rounded-xl p-2 w-20 text-center absolute top-2 right-2 font-pokemonGB border-white border-2">
        #{paddedIndex}
      </div>
      <img
        key={id}
        className="scale-125 relative"
        width={150}
        height={150}
        alt={name}
        src={`https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedIndex}.png`}
      />
      <div className="font-pokemonGB text-black bg-white w-auto text-sm text-center capitalize rounded-tl-2xl p-2 absolute right-0 bottom-0 slant-x-[30deg] border-gray-950 border-4 -m-1">
        {name}
      </div>
      <div
        key={Math.random()}
        className=" flex flex-row fixed right-2 top-16 space-x-3"
      >
        {types?.map((item) => (
          <div className="bg-red-500 rounded-lg p-2 capitalize border-gray-950 border-2 ">
            <p>{item.type?.name}</p>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Pokemon;

我试过调用提取没有axios和使用setLoading状态无济于事,理想情况下,所有的口袋妖怪应该按顺序显示。

yeotifhr

yeotifhr1#

你的代码应该看起来更像这样:

useEffect(() => {
  collectPokemon(limit);
}, []);

const collectPokemon = async (limit: number) => {
  const res = await axiosInstance.get(`pokemon?limit=${limit}`);
  const promises = res.data.results.map((name) => mapPokemon(name));
  const pokemons = await Promise.all(promises);
  setPokedex(pokemons);
};

const mapPokemon = async (name: string) => {
  const res = await axiosInstance.get(`pokemon/${name}`);
  return res.data;
};

你不应该在循环中更新状态

相关问题