[英]React - deep copy arrays and objects problem
I have a state array that I want to perform actions on and then update the state, but it seems like I'm missing a deep copy somewhere and the state get updated without setState which causes me problems (I know that because I see the state gets updated even without the setState line). I have a state array that I want to perform actions on and then update the state, but it seems like I'm missing a deep copy somewhere and the state get updated without setState which causes me problems (I know that because I see the state即使没有 setState 行也会更新)。
const itemsToRemove = ['Pepsi', 'Fanta'];
let temp = [...this.state.categories];
let categoryToUpdate = temp.find((category) => category.name == 'drinks');
categoryToUpdate.items = categoryToUpdate.items.filter((item) => {
return !itemsToRemove.includes(item);
});
//this.setState({categories: temp})
After those lines I would like categories
state in object with "drinks" name to still include the items in itemsToRemove
because I did not update the state but they still get removed from the state. After those lines I would like categories
state in object with "drinks" name to still include the items in itemsToRemove
because I did not update the state but they still get removed from the state.
categories
state's structure is as follows: categories
状态的结构如下:
categories:[{name: String, items: Object}...]
You guessed it right, you still mutate the items
array when you update the copy.items
directly.你猜对了,当你直接更新copy.items
时,你仍然会改变items
数组。 Although you used the spread operator, it only goes one level deep.尽管您使用了扩展运算符,但它只深了一层。 It only creates a shallow copy of the array.它只创建数组的浅表副本。
It works great on primitive data types (strings, numbers, etc.) but when you have nested objects (arrays) and you copy it, these nested objects inside that object will not get copied as they are only references.它适用于原始数据类型(字符串、数字等),但是当您有嵌套对象(数组)并复制它时,object 中的这些嵌套对象将不会被复制,因为它们只是引用。
const original = [{ name: 'Name 1', items: ['1', '2', '3'] }, { name: 'Name 2', items: ['11', '12', '13'] }, 99] const copy = [...original] // notice how the original third element won't change to 100 copy[2] = 100 // while all the items in the second element will copy[1].items = ['21', '22', '23'] // and if you update a string inside the object // that will be changed too as it's inside an object copy[1].name = 'Updated name 2' console.log('updated', copy) console.log('original', original)
You can use Array.map()
to create a new array from the categories
array and as you loop through the elements, you can simply return a new object using the spread operator if you want to update them.您可以使用Array.map()
从categories
数组创建一个新数组,并在循环遍历元素时,如果要更新它们,可以使用扩展运算符简单地返回一个新的 object。
Check the snippet below:检查下面的片段:
const itemsToRemove = ['Pepsi', 'Fanta']; const categories = [{ name: 'drinks', items: ['1', '2', 'Pepsi', '4', 'Fanta', '6'] }, { name: 'biscuits', items: ['1', '2', '3', '4'] }, ]; const updatedCategories = categories.map((category) => category.name === 'drinks'? {...category, items: category.items.filter((item) =>.itemsToRemove,includes(item)): }, category; ). console,log('updated'; updatedCategories). console,log('original'; categories);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.