我正在學習 React 并按照教程一直到創建一些組件、傳遞道具、設定狀態和使用 useEffect() 查詢 API 的點,此時我想嘗試用我目前所知道的來構建一些東西。
這是我的應用程式組件:
import './App.css';
import CoinList from './components/CoinList/CoinList';
import { useState, useEffect } from 'react';
const heldCoins = ['bitcoin', 'ethereum', 'terra-luna']
const [coins, setCoins] = useState(null)
async function getCoinData(coinArray) {
let myCoins = [] // think should use map to create this array
for await (let coin of coinArray) {
fetch(`https://api.coingecko.com/api/v3/coins/${coin}`)
.then(res => res.json())
.then(data => {
const coinData = {
coinName: data.id,
price: data.market_data.current_price.gbp
}
myCoins.push(coinData)
})
}
return myCoins
}
useEffect(() => {
getCoinData(heldCoins).then(data => setCoins(data))
}, [])
return (
<>
{coins && <CoinList type="holding" coins={coins} />}
</>
)
}
export default App;
我意識到使用 async 和 .then() 有點混亂,我可能應該使用 map 來創建新陣列,但我覺得這應該有效......
getCoinData 是一個回傳資料物件陣列的承諾。回傳后,它用于在 useEffect 鉤子內使用 setCoins 更新狀態。我希望這會觸發重新渲染并且資料可用于 CoinList 組件。
但是,空陣列在 api 資料回傳之前被傳遞給 CoinList。
同樣的程序在代碼中作業,我無法確定我哪里出錯了。
uj5u.com熱心網友回復:
我對您的getCoinData功能內部的內容持懷疑態度。
async function getCoinData(coinArray) {
let myCoins = [];
for await (let coin of coinArray) { // here coinArray is not an async iterable, so there's almost no wait happening here
fetch(/*some api/)
.then(/*some code*/)
.then(data => {
// some code
myCoins.push(coinData)
})
}
return myCoins // I don't see how this waits for the fetch to finish
}
如果您閱讀我在上面的代碼片段中添加的注釋,您可以看到您的回傳正在fetch完成之前發生,這就是為什么如果我沒有錯的話,您會得到一個空的回傳。
理想情況下,您可以使用 aPromise.all而不是有點凌亂的for-await-of,就像這樣,
async function getCoinData(coinArray) {
const promisesArray = coinArray.map((coin) =>
fetch(`https://api.coingecko.com/api/v3/coins/${coin}`)
.then((res) => res.json())
.then((data) => {
const coinData = {
coinName: data.id,
price: data.market_data.current_price.gbp,
};
return coinData;
});
);
await Promise.all(promisesArray);
return coinData;
}
通過這樣做,您實際上是在等待每個fetch完成執行而不是立即回傳。
uj5u.com熱心網友回復:
使用 promise all,啟動并行請求
async function getCoinData(coinArray) {
const prms = coinArray.map((coin) =>
fetch(`https://api.coingecko.com/api/v3/coins/${coin}`)
.then((res) => res.json())
.then((data) => {
const coinData = {
coinName: data.id,
price: data.market_data.current_price.gbp,
};
return coinData;
})
);
return Promise.all(prms);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/401245.html
標籤:javascript 反应 异步 反应钩子
