React 如何克隆道具
React how to clone props
我在学习
我的组件中的这个函数有问题:
...
export default function Main(props) {
...
...
...
const deleteMessage = (index) => {
let test = props.data.contacts;
// let test2 = { ...props.data.contacts}; Also tried with this
test[currentContact].messages.splice(index, 1);
// props.setData({ ...props.data, test }) this is commented and should't be executed
}
return (...<JSX Elements>...)
}
当我 运行 <li onCLick={() => deleteMessage(index)}> Delete this message </li>
更改是在父组件的状态上执行的。
虽然在本示例代码中注释掉了props.setData(),但是props.data仍然受到该函数变化的影响
如何在新对象中克隆 props.data 并只处理这个对象,而不更改 props.data?
克隆是正确的方法,我们通常希望避免直接改变数组/对象。
我认为克隆数组或对象的最常见的现代方法是通过 spread operator.
将其内容传播到新变量中
例子-
const originalArray = [1, 2, 3, 4];
const originalObject = {
'a': 1,
'b': 2,
'c': 3,
'd': 4,
};
const newArray = [...originalArray, 5, 6];
const newObject = {
...originalObject,
'e': 5,
'f': 6,
};
console.log(newArray); // [1, 2, 3, 4, 5, 6]
console.log(newObject); // {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
如您所见,它充当数组/对象中的成员,本质上是在创建新变量的同时传播原始变量,而不是对原始变量的引用。
更新状态时,请确保嵌套结构的每个部分都被克隆,直到您到达要更新的实际内容。
test[currentContact].messages.splice(index, 1);
这很糟糕,因为 splice
修改了 messages
数组。
事实上 test[currentContact].messages
本身就很糟糕,因为 test[currentContact]
正在发生变异。
// let test2 = { ...props.data.contacts}; Also tried with this
对象和数组扩展语法可用于克隆和防止变异,但这里也要确保先克隆 props.data
,然后再克隆 contacts
。
不可变地更新数组和对象的示例:
const bla = {
foo: {
bar: [1]
}
}
// here's how you can update `bla` immutably if you want to add an element to the nested array
const clonedBla = { ...bla,
foo: {
...bla.foo,
bar: [...bla.foo.bar, 2]
}
}
console.log(bla, clonedBla)
const bla = {
foo: [{
a: "a",
},
{
b: "b",
arr: [1, 2],
},
],
};
// if we want to remove the second element of `bla.foo[1].arr`
const updatedBla = {
...bla,
foo: bla.foo.map((el, index) =>
index === 1 ?
{
...el,
arr: el.arr.filter((_, iIndex) => iIndex !== 1),
} :
el
),
};
console.log(updatedBla)
我在学习
我的组件中的这个函数有问题:
...
export default function Main(props) {
...
...
...
const deleteMessage = (index) => {
let test = props.data.contacts;
// let test2 = { ...props.data.contacts}; Also tried with this
test[currentContact].messages.splice(index, 1);
// props.setData({ ...props.data, test }) this is commented and should't be executed
}
return (...<JSX Elements>...)
}
当我 运行 <li onCLick={() => deleteMessage(index)}> Delete this message </li>
更改是在父组件的状态上执行的。
虽然在本示例代码中注释掉了props.setData(),但是props.data仍然受到该函数变化的影响
如何在新对象中克隆 props.data 并只处理这个对象,而不更改 props.data?
克隆是正确的方法,我们通常希望避免直接改变数组/对象。
我认为克隆数组或对象的最常见的现代方法是通过 spread operator.
将其内容传播到新变量中例子-
const originalArray = [1, 2, 3, 4];
const originalObject = {
'a': 1,
'b': 2,
'c': 3,
'd': 4,
};
const newArray = [...originalArray, 5, 6];
const newObject = {
...originalObject,
'e': 5,
'f': 6,
};
console.log(newArray); // [1, 2, 3, 4, 5, 6]
console.log(newObject); // {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
如您所见,它充当数组/对象中的成员,本质上是在创建新变量的同时传播原始变量,而不是对原始变量的引用。
更新状态时,请确保嵌套结构的每个部分都被克隆,直到您到达要更新的实际内容。
test[currentContact].messages.splice(index, 1);
这很糟糕,因为 splice
修改了 messages
数组。
事实上 test[currentContact].messages
本身就很糟糕,因为 test[currentContact]
正在发生变异。
// let test2 = { ...props.data.contacts}; Also tried with this
对象和数组扩展语法可用于克隆和防止变异,但这里也要确保先克隆 props.data
,然后再克隆 contacts
。
不可变地更新数组和对象的示例:
const bla = {
foo: {
bar: [1]
}
}
// here's how you can update `bla` immutably if you want to add an element to the nested array
const clonedBla = { ...bla,
foo: {
...bla.foo,
bar: [...bla.foo.bar, 2]
}
}
console.log(bla, clonedBla)
const bla = {
foo: [{
a: "a",
},
{
b: "b",
arr: [1, 2],
},
],
};
// if we want to remove the second element of `bla.foo[1].arr`
const updatedBla = {
...bla,
foo: bla.foo.map((el, index) =>
index === 1 ?
{
...el,
arr: el.arr.filter((_, iIndex) => iIndex !== 1),
} :
el
),
};
console.log(updatedBla)