如何在React Native中使用对象设置空数组的状态

时间:2019-01-21 07:24:07

标签: react-native

  constructor(props) {
    super(props);

    this.state = {
      orders: []

    };
  }


  componentDidMount(){

    AsyncStorage.getItem('uname')
    .then((item) => {
       if (item) {
         id = item
         fetch('www.url.com', {
         method: 'GET',

       }).then((response) => response.json())
             .then((responseJson) => {

             if(!responseJson.error){
               var length = responseJson.result.length

               for(var i = 0 ; i < length ; i++){
                 const orders = [...this.state.orders];
                 const bookingData = responseJson.result;
                 bookingData.map((booking, index) => {
                      orders[index]["bid"] = booking.Booking.id
                      orders[index]["date"] = booking.Booking.booking_date
                      orders[index]["price"] = booking.Booking.booking_amt
                      orders[index]["quantity"] = booking.Booking.qty
                   });
                 this.setState({orders});


               }

             }
             else{
               Alert.alert("Cant Connect toSErber");
             }


             }).catch((error) => {
               console.error(error);
             });

     }
     else {  }
    });

  }

我正在尝试从服务器获取数据并将其存储在状态已定义的订单数组中。现在订单中的每个条目都将具有其ID,价格,数据和数量。但这给了我错误:

Undefined is not an object(evaluating 'orders[index]["bid"]=booking.Booking.id')

我在这里做错了什么?我正在尝试存储顺序排列的对象数组,其中每个对象都有ID,价格,日期和数量字段

1 个答案:

答案 0 :(得分:0)

您的订单数组中没有任何内容,然后尝试访问未定义的订单[index]。这就是为什么出现错误的原因。 在.map内添加以下行。它应该是.map中的第一行。实际应该是.forEach,因为您没有使用.map的结果。

bookingData.forEach(( booking,index) => {
   orders[index] = {}
    // remaining code here 
}

或者您可以创建对象并将其设置为索引

bookingData.forEach((booking, index) => {
  let order = { 
    bid: booking.Booking.id, 
    date: booking.Booking.booking_date,
    price: booking.Booking.booking_amt,
    quantity: booking.Booking.qty
  }
  orders[index] = order
});

但是您确实应该使用forEach,因为map返回一个新数组。

代码重构

在进一步检查代码时,有些事情没有意义。您正在更新componentDidMount中的订单,因此orders的初始状态将是[],所以为什么要复制初始状态的值?其次,您使用的是for循环,但是除了多次执行相同的代码外,您没有对for循环执行任何操作,该代码不依赖于for循环,因此可以删除for循环。

这里是代码的重构,可以使事情更容易理解

// use async/await
async componentDidMount () {
  try {
    let item = await AsyncStorage.getItem('uname');
    // not sure how you are using the item but I am guessing you are doing something with it in your url
    let response =  await fetch(`www.url.com/${item}`, { method: 'GET'});
    let responseJson = await response.json();

    if (!responseJson.error) {
      if (responseJson.result.length) {
        // the map function creates a new array from the old array
        const newOrders = responseJson.result.map(booking => {
          return {
              bid: booking.Booking.id, 
              date: booking.Booking.booking_date,
              price: booking.Booking.booking_amt,
              quantity: booking.Booking.qty
          }
        });
        // save this new array to state
        this.setState({orders: newOrders});
      }
    } else {
      Alert.alert("Cant Connect toSErber");
    }
  } catch (err) {
    console.warn(err);
  }
}

我使用async/await而不是promises,因为它允许使用更简洁的代码。您可以在https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8上了解更多信息。 try/catch将捕获await函数引发的所有错误。然后,我使用地图来创建新的订单数组,然后将其设置为状态。