我如何阻止 redux 状态发生变异
How do i stop redux state from mutating
这以某种方式改变了我的 redux 状态。我不知道为什么:
allProducts 是我商店中的一个状态 initial_state of [] 并从 api 调用中获取值。
const [products, setProducts] = useState([])
const prevProducts = [...allProducts];
setProducts(prevProducts);
const updateProductPrice = (newPrice, index) => {
const newProducts = [...products];
newProducts[index].price = newPrice;
setProducts(newProducts);
console.log(allProducts);
}
当我 console.log(allProducts) 时,它向我显示一个更新后的数组,其中包含 newProducts
的值
我认为您所看到的与 JavaScript 如何在数组中存储对象引用有关。当您复制一个数组时,您不会完全重新创建其中的所有对象,即使在使用扩展运算符时,您也只是复制对每个索引处对象的引用。
换句话说,假设它们共享匹配索引,newProducts[i] 中的每个项目 === allProducts[i] - 即是完全相同的对象实例。
例如,请参阅 https://javascript.info/object-copy,还有许多关于对象“浅”和“深”复制的参考资料。
即使我更改了引用,对象在内存中也是相同的。
“分配给对象的变量存储的不是对象本身,而是它的“内存中的地址”——换句话说就是对它的“引用”。”
我使用了 https://lodash.com/docs/4.17.15#cloneDeep
中的 _.cloneDeep
所以我将代码更改为:
const prevProducts = _.cloneDeep(allProducts);
setProducts(prevProducts);
另一种解决方案:如果您不想使用 lodash.clonedeep 包,您可以使用以下方法进行同样的操作:
const array = [{a: 1}]//initial array
const copy = array.map(item => ({...item}))
这以某种方式改变了我的 redux 状态。我不知道为什么: allProducts 是我商店中的一个状态 initial_state of [] 并从 api 调用中获取值。
const [products, setProducts] = useState([])
const prevProducts = [...allProducts];
setProducts(prevProducts);
const updateProductPrice = (newPrice, index) => {
const newProducts = [...products];
newProducts[index].price = newPrice;
setProducts(newProducts);
console.log(allProducts);
}
当我 console.log(allProducts) 时,它向我显示一个更新后的数组,其中包含 newProducts
的值我认为您所看到的与 JavaScript 如何在数组中存储对象引用有关。当您复制一个数组时,您不会完全重新创建其中的所有对象,即使在使用扩展运算符时,您也只是复制对每个索引处对象的引用。
换句话说,假设它们共享匹配索引,newProducts[i] 中的每个项目 === allProducts[i] - 即是完全相同的对象实例。
例如,请参阅 https://javascript.info/object-copy,还有许多关于对象“浅”和“深”复制的参考资料。
即使我更改了引用,对象在内存中也是相同的。
“分配给对象的变量存储的不是对象本身,而是它的“内存中的地址”——换句话说就是对它的“引用”。”
我使用了 https://lodash.com/docs/4.17.15#cloneDeep
中的 _.cloneDeep所以我将代码更改为:
const prevProducts = _.cloneDeep(allProducts);
setProducts(prevProducts);
另一种解决方案:如果您不想使用 lodash.clonedeep 包,您可以使用以下方法进行同样的操作:
const array = [{a: 1}]//initial array
const copy = array.map(item => ({...item}))