即使在GET和setState之后也无法读取数组

时间:2018-09-24 16:02:26

标签: javascript reactjs express

GET请求,该请求提取特定用户的所有订单。奇怪的设置,但确实可以正确提取数据。

    var all = [];
    axios.get('/api/orders/' + this.props.user.name)
    .then(function (res) {
        res.data.forEach(e => {
            e.orders.forEach(eachOrder => {
                 all.push (
                    eachOrder
                )
            })  
        })
        console.log('this be all: ', all);
    })
    this.setState({
        orders : all
    });

eachOrder确实会打印订单(针对每个订单):

{type: "Pizza", extraType: "na", extraInfo: "na", date: "", quantity: "1", …}

这就是所有console.log:

(5) [{…}, {…}, {…}, {…}, {…}]
0: {type: "Pizza", extraType: "na", extraInfo: "na", date: "", quantity: "1", …}
1: {type: "na", extraType: "Can", extraInfo: "Diet Coke", date: "", quantity: "1", …}
2: {type: "na", extraType: "Can", extraInfo: "Diet Coke", date: "", quantity: "1", …}
3: {type: "na", extraType: "1 Pound", extraInfo: "Honey Garlic", date: "", quantity: "1", …}
4: {type: "na", extraType: "1 Pound", extraInfo: "Honey Garlic", date: "", quantity: "1", …}
length: 5
__proto__: Array(0)

完美,正是我所期望的。我对所有国家都下达了命令。但是命令似乎很奇怪?

if (this.state.orders !== null) {
  console.log('lets see the order: ', this.state.orders)
}

让我们看订单..:

[]
0: {type: "Pizza", extraType: "na", extraInfo: "na", date: "", quantity: "1", …}
1: {type: "na", extraType: "Can", extraInfo: "Diet Coke", date: "", quantity: "1", …}
2: {type: "na", extraType: "Can", extraInfo: "Diet Coke", date: "", quantity: "1", …}
3: {type: "na", extraType: "1 Pound", extraInfo: "Honey Garlic", date: "", quantity: "1", …}
4: {type: "na", extraType: "1 Pound", extraInfo: "Honey Garlic", date: "", quantity: "1", …}
length: 5
__proto__: Array(0)

我无法检查订单的.length,我无法mapforEach,什么也没有。我无法检查以太数组中的元素。

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

您需要在HTTP异步请求的回调中setState。由于您的this参考已被重定向到function(res) {},因此您将收到承诺拒绝错误。

当您使用function关键字而不是ES6箭头函数进行回调(这也是编写React组件方法的最佳实践)时,会发生很多情况

这是您可以做的,将function() {}替换为() => {}

var all = [];
axios.get('/api/orders/' + this.props.user.name)
.then((res) => {   //change function to arrow function
    res.data.forEach(e => {
        e.orders.forEach(eachOrder => {
             all.push (
                eachOrder
            )
        })  
    })
    this.setState({
        orders : all
    });
    console.log('this be all: ', all);
})

或者,如果您需要或希望继续使用function关键字作为回调,则可以将component方法转换为箭头函数,以将this的引用绑定到组件

mySexyMethod = () => {
    var all = [];
    axios.get('/api/orders/' + this.props.user.name)
    .then(function (res) {
        res.data.forEach(e => {
            e.orders.forEach(eachOrder => {
                 all.push (
                    eachOrder
                )
            })  
        })
        this.setState({
          orders : all
        });
        console.log('this be all: ', all);
    })
}

但是,无论您决定采用哪种解决方案,问题的第一个也是最重要的部分是您的setState不在异步请求的回调中,只需将其移到该块中即可使其工作。 / p>

答案 1 :(得分:1)

您的setState在提取调用完成之前正在运行,因为它在then块之外。另外,要访问this块内的then,还需要使axios回调函数成为箭头函数:

.then((res) => {

它可能看起来像这样:

axios.get('/api/orders/' + this.props.user.name)
.then((res) => {
  const orders = res.data.reduce((acc, e) => {
    return [...acc, ...e.orders]
  }, [])
  this.setState({orders})
})

答案 2 :(得分:1)

then块使用箭头功能,并向内移动setState。那应该做。

看看这个文档,可能对https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html有帮助

答案 3 :(得分:1)

这应该有效。至少在这里https://github.com/mustafamamun/Test/blob/master/UI/src/App.js

axios.get('/api/orders/' + this.props.user.name)
.then(res=> {
    res.data.forEach(e => {
        e.orders.forEach(eachOrder => {
             all.push (
                eachOrder
            )
        })  
    })
    console.log('this be all: ', all);
    this.setState({
      orders : all
    });
})