我正在尝试使用 forEach 循环将多个对象添加到状态数组:
const App = () => {
const [pokemon, setPokemon] = useState([]);
axios.get('https://pokeapi.co/api/v2/pokemon') // Gives me 20 pokemon
.then(res => {
res.data.results.map(p => p.url).forEach(url => { // Loops over endpoints of pokemon
axios.get(url)
.then(response => {
setPokemon(response.data)
})
});
})
}
正如您可能猜到的,当我 console.log pokemon 时,只显示 forEach 循环中的最后一项,因为它是在状态中设置的最后一项。
我正在使用的 API:https://pokeapi.co/。
我从调用 https://pokeapi.co/api/v2/pokemon 开始,它给了我 20 个 pokemon,每个 pokemon 对象都带有一个端点以获取有关它的更多信息,我想将这些端点的信息作为对象存储在状态中.
感谢您的帮助,如果您知道更好的方法,请随时告诉我。
答案 0 :(得分:1)
只需创建一个临时数组,将您从 API 获取的所有数据添加到该数组中,然后使用该变量设置状态。您不必每次都设置状态 - 您可以一次设置它。
const App = () => {
const [pokemon, setPokemon] = useState([]);
const tempArr = [];
axios.get('https://pokeapi.co/api/v2/pokemon') // Gives me 20 pokemon
.then(res => {
res.data.results.map(p => p.url).forEach(url => { // Loops over endpoints of pokemon
axios.get(url).then(response => {
tempArr.push(response.data);
})
});
});
setPokemon(tempArr);
}
答案 1 :(得分:1)
我建议您在 Promise.all()
钩子内使用 useEffect()
。通过使用 useEffect,您可以在组件挂载时(而不是每次渲染时)运行一次获取代码。使用 Promise.all()
允许您传递一个 promises 数组(这是 axios.get()
返回的内容),并将每个 Promise 解析为一个。这个 Promise 可以解析为每个 axios.get() 调用导致的一系列响应。这允许您只设置一次状态。
参见工作示例:
const {useState, useEffect} = React;
const App = () => {
const [pokemon, setPokemon] = useState([]);
useEffect(() => {
axios.get('https://pokeapi.co/api/v2/pokemon')
.then(res => Promise.all(res.data.results.map(pokemon => axios.get(pokemon.url))))
.then(arr => setPokemon(arr.map(response => response.data)));
}, []);
return (<div>
{pokemon.map(({id, species}) => <p key={id}>{species.name}</p>)}
</div>);
}
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js" integrity="sha512-bZS47S7sPOxkjU/4Bt0zrhEtWx0y0CRkhEp8IckzK+ltifIIE9EMIMTuT/mEzoIMewUINruDBIR/jJnbguonqQ==" crossorigin="anonymous"></script>
答案 2 :(得分:0)
试试 setPokemon([...pokemon , response.data] )
答案 3 :(得分:0)
你可能应该使用
setPokemon (pokemon.concat(response.data)