我使用axios发出HTTP请求,在其中我发出另一个HTTP请求,以便添加有关我获得的项目的一些细节。我将它推送到'orders'数组后我需要setState,但它之前就这样做了所以我不能以正确的方式打印它。 它适用于SetTimeout但我想以更专业的方式做到这一点。 我怎么能同步?
fetchOrders(){
let orders = [];
let status;
this.setState({loading:true});
http.get('/api/amazon/orders')
.then(response => {
if (response.status === 200) status = 200;
orders = response.data;
orders.map(order => {
order.SellerSKU = "";
http.get(`/api/amazon/orders/items/${order.AmazonOrderId}`)
.then(res => {
order.SellerSKU = res.data[0].SellerSKU;
})
.catch(error => {
console.log(error);
})
});
setTimeout( () => {
this.setState({orders, error: status ? false : true, loading:false})
}, 1000);
})
.catch(error => {
this.setState({loading:false, error:true});
console.error(error);
});
}
答案 0 :(得分:2)
你似乎在问错误的问题,即如何实现异步同步,而你真的试图推迟设置你的状态,直到一切都完成。 (又名XY Problem)
您不需要使setState
同步 - 您只需要利用一些承诺链和Promise.all
,这样您就可以推迟setState
调用,直到所有内容都是结束。
简而言之,您应该能够根据需要对此进行调整,并对响应进行一些转换:
fetchOrders() {
http.get('/first')
.then(r => r.data)
.then(orders => {
// This wraps the iterable of promises into another promise
// that doesn't resolve until all the promises in the iterable
// have finished.
return Promise.all(orders.map((order) => http.get(`/second/${order.id}`).then(/* transform */))
})
.then(transformedOrderPromises => this.setState({ ... });
}
答案 1 :(得分:1)
setState可以采用回调函数,在完成mutate状态后,它将执行回调。因此,您可以setState
在回调中添加第二个API调用。
这样的事情:
http.get('/api/amazon/orders')
.then(response => {
if (response.status === 200) status = 200;
orders = response.data;
this.setState({orders, error: status ? false : true, loading:false},
() => {
orders.map(order => {
order.SellerSKU = "";
http.get(`/api/amazon/orders/items/${order.AmazonOrderId}`)
.then(res => {
order.SellerSKU = res.data[0].SellerSKU;
}).catch(error => {
console.log(error);
})
});
})
请注意,我刚编辑了一个肮脏的方式,可能需要进行一些调整才能使其正常工作。
答案 2 :(得分:-3)
在我的项目中,我伪造了同步setState
以避免很多陷阱,使代码更清晰。这是我的所作所为:
class MyComponent extends React.Component {
// override react's setState
setState(partialState) {
const mergedState = { ...this.state, ...partialState };
this.state = mergedState;
super.setState(partialState);
}
}
解释:在调用真setState
之前,状态也设置为this.state
,以便在实际更新之前对它的任何引用都是正确的。
唯一的缺点是你必须从MyComponent
而不是React.Component
延伸。