在 React 中映射时处理多个 get 请求

问题描述

我有一个组件,其中我通过数组 map() 来呈现子组件。

这是我的代码的一部分:

// example pokemons
const pokemons = [
  {
    id: 1  
    name: "bulbasaur"
  },{
    id: 2,name: "ivysaur"
  },{
    id: 3,name: "venusaur"
  }
];

// map through pokemons
const mappedPokemons = pokemons.map((p,i) => {
  return <Pokemon key={i} pokemon={p} />;
});

// render
return (
  <div className="ml-3">
    <h1 className="text-center mb-5">Pokémons:</h1>
    <div className="row">{mappedPokemons}</div>
  </div>
);

在子组件中,使用 axios 完成获取请求,以从公共 API (pokeapi) 获取数据。

const [pm,setPm] = useState(null);

useEffect(() => {
  axios
    .get("https://pokeapi.co/api/v2/pokemon/" + pokemon.id)
    .then((response) => {
      setPm(response.data);
    })
    .catch((error) => {
      console.log(error);
    });
},[pokemon.id]);

我想要实现的是在渲染组件之前等待接收到所有数据,我听说过 Promise.all(),但不确定在何处实现它,如果这是正确的方法

我制作了这个 sandbox 以便您可以尝试一些东西。

解决方法

如果状态被放入父组件中,您可以轻松等待所有解决方案。将 pokemons 置于状态,然后:

// parent
useEffect(() => {
  Promise.all(
    pokemons.map(p => axios
      .get("https://pokeapi.co/api/v2/pokemon/" + p.id)
      .then(res => res.data)
    )
  )
  .then((allData) => {
    const combined = pokemons.map((p,i) => ({ ...p,data: allData[i] }));
    setPokemons(combined);
  })
  .catch(handleErrors); // don't forget this
},[]);

然后,仅在 pokemons[0].data 存在时才渲染子组件,并根据需要使用 pokemon 属性中的数据。