无法在 .then() 中运行函数 Axios React



我有一个网页,在那里我用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状态变量,但在设置状态之前调用了calculateTrendcalculateTrendDirection,因为更新状态值是分批的。

这个问题有几种解决办法。

解决方案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);
}

最新更新