My useEffect填充tempStocksData,当Promise实现时,它被传递给setStockData()。如下面的代码所示,打印出tempStocksData和stockData,它们应该在我调用setStockData(tempStocksData)之后被填充。您可以看到Promise已经实现了,因为它执行了打印。但是,stockData是空的。由于某种原因,setStockData不能工作,因为stockData没有被填充。下面是供参考的代码:
const [ stockData, setStockData ] = useState([])
const getStocksData = (stock) => {
return axios.get(`${BASE_URL}?symbol=${stock}&token=${TOKEN}`).catch((error) => {
console.error("Error", error.message)
})
}
useEffect(()=> {
let tempStocksData = []
const stocksList = ["AAPL", "MSFT", "TSLA", "FB", "BABA", "UBER", "DIS", "SBUX"];
let promises = [];
stocksList.map((stock) => {
promises.push(
getStocksData(stock)
.then((res) =>
{tempStocksData.push({
name: stock,
...res.data
})
})
)
})
Promise.all(promises).then(()=>{
console.log(tempStocksData)
setStockData(tempStocksData)
console.log(stockData)
})
}, [])
请帮我解决这个问题。让我知道,如果有什么东西我错过了,或者我正在做的东西,是不是最新的版本/依赖关系,或者如果我做Promise() js错误。
你甚至进入你的Promise.all
序列开始吗?
在获得stockdata后,您已经通过.then
函数结束了承诺。
stocksList.map((stock) => {
promises.push(
getStocksData(stock)
)
})
Promise.all(promises).then((result)=>{
const tempStocks = result.map((stock) => {
return {
name: stock.name,
data: stock.data
}
});
console.log(tempStocksData)
setStockData(tempStocksData)
console.log(stockData)
})
注意:上面的代码是未经测试的,但是用来显示点
在setStockData
时尝试使用扩展操作符这样的
setStockData([...tempStocksData])
既然我今天在查找setData问题时偶然发现了这个问题,让我澄清一些事情。还有人指出,你对承诺的使用可能并不是你真正想要做的。
无论如何,重要的是要理解stockData
的console.log
在发出setStockData
(甚至的useEffect
内。当setter被调用"before"日志记录尝试)将而不是在控制台中显示更新的数据。
这是因为useState
中的所有setter都在useEffect
调用中批处理在一起,而相应的getter(在本例中为stockData
)将只在下一个呈现循环中反映更新的值。然而,当渲染或任何其他钩子监听stockData
的变化时,它将可用。
你可以在StackBlitz上找到一个示例实现。请注意,即使使用API查询结果更新了视图,console.log
也会显示一个空数组。
来自StackBlitz的代码示例复制在这里:
import * as React from 'react';
import './style.css';
import { useState, useEffect } from 'react';
import axios from 'axios';
const TOKEN = 'IAPYYRPR0LN9K0K4';
const BASE_URL = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE';
export default function App() {
const [stockData, setStockData] = useState([]);
const getStocksData = (stock: string) => {
return axios
.get<{ 'Global Quote': { [data: string]: string } }>(
`${BASE_URL}&symbol=${stock}&apikey=${TOKEN}`
)
.then((result) => result.data)
.catch((error) => {
console.error('Error', error.message);
});
};
useEffect(() => {
const stocksList = ['AAPL', 'MSFT', 'TSLA'];
let promises: Promise<void | {
'Global Quote': { [data: string]: string };
}>[] = [];
stocksList.map((stock) => {
promises.push(getStocksData(stock));
});
Promise.all(promises).then((result) => {
setStockData(result);
console.log(stockData);
});
}, []);
return <pre>{JSON.stringify(stockData, undefined, ' ')}</pre>;
}