ios - 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 })
})
}
解决方案
我看不到您在哪里定义了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 */);
希望能帮助到你!
推荐阅读
- reactjs - 当输入为空时禁用按钮反应
- assembly - 如何为 Assembly 8086 中的给定物理地址设置值?
- javascript - Moment JS 将友好日期转换为 JS 日期
- python - calendar.monthrange() - ValueError:Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()
- c# - 未参考计时器框架 4.8 的对象未释放
- mongodb - 带有 SSL 文件的 MongoDB Jmeter
- php - Slim 4 PUT 和 DELETE 表单提交
- python - 根据列中的组绘制分布图
- c# - 如何在我的 UWP 项目中使用 NewsApi.org?
- perl - 安装 Perl-5.20.2 时出现编译失败错误