Javascript 如何在axios响应后的REACTE中使setState同步

Javascript 如何在axios响应后的REACTE中使setState同步,javascript,reactjs,asynchronous,axios,setstate,Javascript,Reactjs,Asynchronous,Axios,Setstate,我使用axios发出HTTP请求,并在其中发出另一个HTTP请求,以便添加有关我获得的项目的一些详细信息。我需要在我将其推送到“orders”数组后设置state,但它之前已经设置了,所以我无法以正确的方式打印它。 它与SetTimeout一起工作,但我想用更专业的方式来做。 我怎样才能做到呢 fetchOrders(){ let orders = []; let status; this.setState({loading:true}); http.get('/

我使用axios发出HTTP请求,并在其中发出另一个HTTP请求,以便添加有关我获得的项目的一些详细信息。我需要在我将其推送到“orders”数组后设置state,但它之前已经设置了,所以我无法以正确的方式打印它。 它与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);
        });
}
可以取一个回调函数,在完成状态变异后,它将执行回调。因此,您可以
setState
并在回调中添加第二个API调用

大概是这样的:

http.get('/api/amazon/orders'))
。然后(响应=>{
如果(response.status==200)status=200;
订单=响应数据;
this.setState({orders,error:status?false:true,load:false},
() => {
orders.map(order=>{
order.SellerSKU=“”;
http.get(`/api/amazon/orders/items/${order.AmazonOrderId}`)
。然后(res=>{
order.SellerSKU=res.data[0].SellerSKU;
}).catch(错误=>{
console.log(错误);
})    
});
})
可以接受回调函数,在完成状态变异后,它将执行回调。因此,您可以
设置状态
并在回调中添加第二个API调用

大概是这样的:

http.get('/api/amazon/orders'))
。然后(响应=>{
如果(response.status==200)status=200;
订单=响应数据;
this.setState({orders,error:status?false:true,load:false},
() => {
orders.map(order=>{
order.SellerSKU=“”;
http.get(`/api/amazon/orders/items/${order.AmazonOrderId}`)
。然后(res=>{
order.SellerSKU=res.data[0].SellerSKU;
}).catch(错误=>{
console.log(错误);
})    
});

})
在我的项目中,我伪造了一个同步的
设置状态
,以避免很多陷阱,使代码更干净。我的做法如下:

class MyComponent extends React.Component {
   // override react's setState
   setState(partialState) {
      const mergedState = { ...this.state, ...partialState };
      this.state = mergedState;
      super.setState(partialState);
   }
}
说明:在调用true
setState
之前,状态也被设置为
this.state
,以便在实际更新之前对它的任何引用都是正确的


唯一的缺点是您必须从
MyComponent
扩展,而不是
React.Component

在我的项目中,我伪造了一个同步
setState
,以避免许多陷阱,使代码更干净。我的做法如下:

class MyComponent extends React.Component {
   // override react's setState
   setState(partialState) {
      const mergedState = { ...this.state, ...partialState };
      this.state = mergedState;
      super.setState(partialState);
   }
}
说明:在调用true
setState
之前,状态也被设置为
this.state
,以便在实际更新之前对它的任何引用都是正确的


唯一的缺点是,您必须从
MyComponent
扩展,而不是
React.Component

您似乎问了一个错误的问题,那就是如何将异步实现为同步,而实际上,您正试图推迟设置状态,直到一切都完成

您不需要使
setState
同步-您只需要利用一些承诺链接和,这将允许您推迟
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({ ... }); 
}

您似乎问了一个错误的问题,即如何将异步实现为同步,而实际上您正试图将状态设置推迟到所有操作完成

您不需要使
setState
同步-您只需要利用一些承诺链接和,这将允许您推迟
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({ ... }); 
}

它应该可以工作,当我打印订单时,一切都正常,但它不会在浏览器中显示“SellerSKU”。因此,在完成映射方法之前,我仍然会将道具转到child。@EliLevit:那么我认为您必须显示使用
res.data[0]的代码块.SellerSKU
它应该可以工作,当我打印订单时,一切都正常,但它不会在浏览器中显示“SellerSKU”。因此,我认为道具在完成映射方法之前会转到child。@EliLevit:那么我想你必须显示使用
res.data[0]的代码块.SellerSKU
这…是一个非常糟糕的主意。您不应该在组件中手动设置状态,如果您需要一个函数在之后运行,请使用
setState
的回调功能。这…是一个非常糟糕的主意。您不应该在组件中手动设置状态,如果您需要一个函数在之后运行,请使用回调函数
setState的个性化