我有正在jsfiddle上测试的这段代码
onVote = (dir, index) => {
console.log(this.state)
const products = [...this.state.products]
products[index].votes = dir ? products[index].votes + 1 : products[index].votes - 1
console.log(this.state.products[index].votes)
// this.setState({products})
};
https://jsfiddle.net/hkL3wug7/2/
但是,即使我没有设置“状态”,控制台日志也会显示每次单击加号和减号时状态都会改变。
相同const newState = [...state] // clone the array
newState[action.index].done = true
return newState
据我了解
(这不是另一个问题的重复,我不是在寻求有效的方法)
答案 0 :(得分:3)
正如@Carcigenicate所说,您已经创建了数组的浅表副本,这意味着您有一个指向原始对象中相同对象的新数组。
为避免变异原始对象,您还需要创建一个您想要变异的对象的副本,例如:
// Shallow copy of the array
const products = [...this.state.products];
// Shallow copy of the object within the array
const updatedProduct = { ...products[index] };
// Update the copy of the object
updatedProduct.votes = dir ? updatedProduct.votes + 1 : updatedProduct.votes - 1;
// Replace the object with the updated copy
products[index] = updatedProduct;
答案 1 :(得分:1)
正如注释中提到的@Carcigenicate,使用散布运算符将创建数组的浅表副本。这给您带来了问题,因为数组的扩展版本包含Object
,这些引用是通过引用传递的。因此,即使您的局部变量products
是this.state.products
的新副本,它们都包含对相同Object
的引用。
要实现您要执行的操作,您必须在this.state.products
中克隆对象。一种可行的方法是使用Object.assign
并将const products = [...this.state.products]
替换为:
const products = [
Object.assign({}, this.state.products.Orange),
Object.assign({}, this.state.products.Apples),
Object.assign({}, this.state.products.Bananas)
]