我有一个网页,在那里我用async axios获取数据,然后用它们进行计算。
以下是代码片段:
const FetchData = async () =>{
console.log("FETCH CALLED");
await Axios.get(`http://localhost:8080/stock/getquote/${props.API}`)
.then(resp => {
setStockData(resp.data);
calculateTrend();
calculateTrendDirection();
})
}
在这里,我得到了calculateTrend((函数的错误。我的问题是,this.then((应该在响应到达时运行,但它似乎以前运行过。因为calculateTrend和calculateTrendDirection都能处理这个提取的数据
编辑:我得到的错误是无法读取未定义的属性"previousClosePrice"。我确信这在物体中存在,所以拼写错误不是的问题
第2版:我根据您的解决方案编辑了我的组件,其中一个恰好有效,唯一的问题是获取进入一个无限循环,每秒获取多次。我怀疑useEffect中的依赖项,但我不确定在那里设置什么。
这是我的完整组件:
function StockCard(props) {
const [FetchInterval, setFetchInterval] = useState(300000);
const [StockData, setStockData] = useState({});
const [TrendDirection, setTrendDirection] = useState(0);
const [Trend, setTrend] = useState(0);
const FetchData = async () =>{
console.log("FETCH CALLED");
const resp = await Axios.get(`http://localhost:8080/stock/getquote/${props.API}`)
setStockData(resp.data);
}
const calculateTrendDirection = () => {
console.log(StockData.lastPrice);
if(StockData.lastPrice.currentPrice > StockData.lastPrice.previousClosePrice){
setTrendDirection(1);
} else if (StockData.lastPrice.currentPrice < StockData.lastPrice.previousClosePrice){
setTrendDirection(-1);
} else {
setTrendDirection(0);
}
}
const calculateTrend = () => {
console.log(StockData.lastPrice);
var result = 100 * Math.abs( ( StockData.lastPrice.previousClosePrice - StockData.lastPrice.currentPrice ) / ( (StockData.lastPrice.previousClosePrice + StockData.lastPrice.currentPrice)/2 ) );
setTrend(result.toFixed(2));
}
useEffect(() => {
FetchData();
if(StockData.lastPrice){
console.log("LÉTEZIK A LAST PRICE")
calculateTrend();
calculateTrendDirection();
}
const interval = setInterval(() => {
FetchData();
}, FetchInterval)
return() => clearInterval(interval);
},[StockData, FetchData, FetchInterval, calculateTrend, calculateTrendDirection]);
return(
<div>
<CryptoCard
currencyName={StockData.lastPrice? StockData.name : "Name"}
currencyPrice={StockData.lastPrice? `$ ${StockData.lastPrice.currentPrice}` : 0}
icon={<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/46/Bitcoin.svg/2000px-Bitcoin.svg.png"/>}
currencyShortName={StockData.lastPrice? StockData.symbol : "Symbol"}
trend={StockData.lastPrice? `${Trend} %` : 0}
trendDirection={StockData.lastPrice? TrendDirection : 0}
chartData={[9200, 5720, 8100, 6734, 7054, 7832, 6421, 7383, 8697, 8850]}
/>
</div>
)
then
块只有在promise完成后才被调用,因此此时数据是可用的。
据我所见,问题是setStockData
试图用响应设置stockData
状态变量,但在设置状态之前调用了calculateTrend
和calculateTrendDirection
,因为更新状态值是分批的。
这个问题有几种解决办法。
解决方案1:
设置状态后,您可以调用以下两个函数:
setStockData(resp.data, () => {
calculateTrend();
calculateTrendDirection();
});
解决方案2:
状态更新后,可以使用useEffect
再次调用函数:
useEffect(() => {
if (stockData) { // or whatever validation needed
calculateTrend();
calculateTrendDirection();
}
}, [stockData]);
解决方案3:
您可以将参数传递给方法:
calculateTrend(resp.data);
calculateTrendDirection(resp.data);
最佳选择?我认为#2,因为它还确保了每当股票数据更新时(无论其他原因(都会重新计算趋势和趋势方向。
我猜在calculateTrend
中,您使用的是setStockData
设置为状态的数据,如果是
setState
不会在您调用setState
之后立即发生,如果您希望在正确更新状态后执行某些操作,则应该查看类似于以下的内容
setStockData(resp.data, () => {
calculateTrend();// this will call once the state gets changed
});
或者你可以使用useEffect
useEffect(() => {
calculateTrend(); // this will call every time when stockData gets changed
}, [stockData])
如果您在calculateTrend函数中使用stockData,并且setStockData是一个异步函数,请使用stockData作为依赖项将calculate趋势函数移动到useEffect,这样每次更新stockData时,calculateTrend和calculateTrendDirection都会被调用:
useEffect(() => {
const interval = setInterval(() => {
FetchData();
}, FetchInterval);
return() => clearInterval(interval);
}, [FetchInterval]);
useEffect(() => {
if(StockData.lastPrice){
console.log("LÉTEZIK A LAST PRICE")
calculateTrend();
calculateTrendDirection();
}
}, [StockData]);
const FetchData = async () =>{
console.log("FETCH CALLED");
const res = await Axios.get(`http://localhost:8080/stock/getquote/${props.API}`);
setStockData(resp.data);
}