[英]Async call to API within map function (React)
所以我目前正在做一個項目,當用戶登陸儀表板頁面時,需要計算給定用戶的持有價值(股票列表及其數量)。 目前,我正在通過 GET 為持有列表中的每個項目調用 API,並計算這些股票的總當前價值。 最后,我得到了股票代碼、當前價值、數量和總額(數量 * 當前價值)。 然后我想通過 render() 中的 map 函數向用戶顯示這些值。
最初,我嘗試在 render 中的 map 函數中獲取和計算所有這些信息,該函數將迭代持有列表。 但是,我什至無法編譯它而不會遇到有關放置在 JSX 中的承諾的錯誤(我正在處理異步)。 我意識到我可以簡單地計算 componentDidMount() 中的列表,所以我選擇了它。
不幸的是,盡管這次它確實可以編譯,但我仍然看到了問題。 在 componentDidMount() 中,我執行以下操作:
const holdings = store.getState().mainApp.portfolio.holdings;
var newHoldings = []
holdings.forEach(async element => {
const stock = await axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`);
let stockPrice = stock.data[0].price
let total = +stockPrice * +element.qty;
newHoldings.push({
ticker: element.ticker,
qty: element.qty,
price: stockPrice,
totPrice: total
})
});
this.setState({ activePortfolio: newHoldings })
這是我在渲染函數中所做的
{this.state.activePortfolio ?
// CONSOLE LOG HERE OF activePortfolio RETURNS THE CALCULATED LIST
this.state.activePortfolio.map((value) =>
// CONSOLE LOG HERE RETURNS NOTHING
console.log(value)
// <div>
// <p>{value.ticker} <span style={{right: '2vw', float: 'right'}}>{value.qty}x @ ${value.price}/ea</span></p>
// <p style={{float: 'right'}}> $ {value.totPrice}</p>
// </div>
)
:
console.log("ERROR ACTIVE P")
}
目前,map 函數只記錄 activePortfolio 中的每個值,但是當我運行它並且有館藏時,它不會記錄任何內容。 但是,如上所示,它確實記錄了列表(如果沒有迭代)。 有誰知道這里發生了什么? 我只是缺少一些小而基本的東西嗎?
謝謝你們!
編輯... (根據@zero298 的評論)
var promises = holdings.map(element => {
return axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`).then(stock => {
let stockPrice = stock.data[0].price
let total = +stockPrice * +element.qty;
return ({
ticker: element.ticker,
qty: element.qty,
price: stockPrice,
totPrice: total
});
})
})
console.log(Promise.all(promises))
Promise.all(promises).then(res => {
newHoldings = res;
});
所以現在當我為 res 設置新的持有量時(順便說一下,當記錄在那里時,res 會正確顯示數組值)它仍然無法在 render() 中的 map 函數中記錄該值。 我在這里做錯了嗎? 我對 Promise 還是有點陌生。
編輯 2...好的! 所以感謝@dave 的幫助和@zero298。 我最終使用了組合解決方案。 上述編輯的唯一問題是我沒有將 componentDidMount() 設為異步函數,也沒有在 Promise.all() 函數上調用 await。 (完全不認為你可以用 componentDidMount() 做到這一點!)這是固定的解決方案......
async componentDidMount(){
*... other init code ...*
var promises = holdings.map(element => {
return axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`).then(stock => {
let stockPrice = stock.data[0].price
let total = +stockPrice * +element.qty;
return ({
ticker: element.ticker,
qty: element.qty,
price: stockPrice,
totPrice: total
});
})
})
console.log(Promise.all(promises))
await Promise.all(promises).then(res => {
newHoldings = res;
});
};
非常感謝你們,我真的很感激你們的幫助!
我想你可能只想做:
await Promise.all(promises).then(res => {
newHoldings = res;
});
如果這不起作用,你可以這樣做:
for await (const holding of holdings) {
const stock = await axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${holding.ticker}`);
let stockPrice = stock.data[0].price
let total = +stockPrice * +holding.qty;
newHoldings.push({
ticker: holding.ticker,
qty: holding.qty,
price: stockPrice,
totPrice: total
})
};
this.setState({ activePortfolio: newHoldings })
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.