首页 > 解决方案 > React Native - 状态中的对象数组未正确更新

问题描述

我真的觉得我在这里要疯了。所以我做了一个购物类型的应用程序,添加到购物车等。

我对每个项目都有额外的评论,用户可以输入他们想要的任何文本。输入的“onChangeText”上的状态是正确的,我用控制台检查了它。但是,当我想保存它时(在编辑购物车之后),尽管 console.log 有意义并且显示了正确的状态等,但options更改成功,但comments没有。这很奇怪,因为除了注释之外,所有其他购物车数组对象都发生了变化。这是代码:

saveItemCart() {
    var index = this.state.cartItems.indexOf(x => x.date === this.state.dateAdded);
    let cartItemsArray = this.state.cartItems;
    temp = { 'catNumber': this.state.catNumber, 'itemNumber': this.state.itemNumber, 'quantity': this.state.itemQuantity, 'options': this.state.selectedOptions, 'date': this.state.dateAdded, 'comments': this.state.commentsText};
    cartItemsArray[index] = temp;

    this.setState({ cartItems: cartItemsArray }, () => {
        this.updateTotal();
        this.setState({ selectedOptions: [], checked: [] })
    })
}

状态:

state = {
        ModalItemShown: false,
        ModalCartShown: false,
        ModalEditShown: false,

        isShowToast: false,
        isShowToastError: false,

        rest_id: this.props.route.params['restaurantid'],
        menuData: this.getMenu(),
        catNumber: 1,
        itemNumber: 1,
        dateAdded: null,
        commentsText: "",
        cartItems: [],

        checked: [],
        selectedOptions: [],

        total: 0,
        itemQuantity: 1,
    }

输入(在渲染内):

    <View style={styles.modalOptions}>
          <Input placeholder="..." placeholderTextColor="gray" defaultValue={this.state.commentsText} onChangeText={text => this.setState({ commentsText: text }, () => {console.log(this.state.commentsText)})} />
     </View>
<Button shadowless style={styles.button1} color="warning" onPress={() => {
      let my = this;
      this.showToast(true);
      setTimeout(function () { my.showToast(false) }, 1000);
      this.saveItemCart();
      this.hideModalEdit(false);
      }}
 >Save</Button>

问题出在编辑购物车模式(即页面)的输入中。如果用户在将评论添加到购物车之前首先放置评论,那么当他打开编辑模式时,它会得到正确的评论。如果我在编辑中更改它并单击保存,然后再次检查,它不起作用。

更新总计:

updateTotal() {
        var cartArrayLen = this.state.cartItems.length;
        var i;
        var j;
        var total = 0;
        var cart = this.state.cartItems;

        for (i = 0; i < cartArrayLen; i++) {
            var catNum = cart[i]["catNumber"];
            var itemNum = cart[i]["itemNumber"];
            var q = cart[i]["quantity"];


            var itemPrice = this.state.menuData[catNum - 1][catNum.toString()]["itemsarray"][itemNum]["price"];
            itemPrice = Number(itemPrice.replace(/[^0-9.-]+/g, ""));
            total = total + (itemPrice * q);

            var allItemOptions = this.state.menuData[catNum - 1][catNum.toString()]["itemsarray"][itemNum].options;

            var k;
            for (k = 0; k < cart[i].options.length; k++) {
                var title = cart[i].options[k]["title"];
                var index_onmenu = allItemOptions.findIndex(x => x.title === title);

                var option_price;
                if (Array.isArray(cart[i].options[k].indexes)) {
                    for (j = 0; j < cart[i].options[k].indexes.length; j++) {
                        var price_index = cart[i].options[k].indexes[j];

                        option_price = allItemOptions[index_onmenu].price[price_index]
                        total = total + Number(option_price) * q
                    }
                } else {
                    j = cart[i].options[k].indexes
                    option_price = allItemOptions[index_onmenu].price[j]
                    total = total + Number(option_price) * q
                }
            }

        };
        console.log("New Total: " + total);
        this.setState({ total: total }, () => {
            this.setState({ itemQuantity: 1 })
        })
    }

标签: iosreactjsreact-nativestate

解决方案


我看不到您在哪里定义了temp变量,但假设它是在某处定义的,我认为问题在于您如何更新 cartItems 数组。让我通过在您的代码中添加一些注释来解释它:

saveItemCart() {
    var index = this.state.cartItems.indexOf(x => x.date === this.state.dateAdded);
    let cartItemsArray = this.state.cartItems; // --> Here you are just copying the array reference from the state
    temp = { 'catNumber': this.state.catNumber, 'itemNumber': this.state.itemNumber, 'quantity': this.state.itemQuantity, 'options': this.state.selectedOptions, 'date': this.state.dateAdded, 'comments': this.state.commentsText};
    cartItemsArray[index] = temp;

    this.setState({ cartItems: cartItemsArray }, () => { // --> then you just updated the content of the array keeping the same reference
        this.updateTotal();
        this.setState({ selectedOptions: [], checked: [] })
    })
}

尝试创建一个新数组,以便 react 浅比较算法可以跟踪状态变化,如下所示:

this.setState({ cartItems: Array.from(cartItemsArray) }, /* your callback */);

或者

this.setState({ cartItems: [...cartItemsArray]}, /* your callback */);

希望能帮助到你!


推荐阅读