我正在从父组件获取对象并将其设置为状态。在子组件中,我正在更新状态,但父引用对象值也会更改,而不仅仅是状态更改。
父组件有一个巨大的对象,
obj = {
values: {
per1: { name: "rsk" },
per2: { name: "ssk" },
}
}
子组件:
const ChildComponent = ({obj}) => {
const [inp, setInp] = useState(obj.values);
const onChange = useCallback(({target}) => {
setInp((prev) => {
const nD = { ...prev };
//k1, k2 comes from some logic
nD[k1][k2] = target.value;
return nD;
})
}, []);
return (
Here the "inp" state is looped by objects and keys in text box to build a html form
)
}
这里的问题是,为什么核心obj.值也在onChange setInp时间更改。我不想在提交表单之前干扰obj.值。因为在提交表单之前,我需要验证,
对象值是否等于inp状态值
对这个有什么想法。
2条答案
按热度按时间lsmd5eda1#
原来的对象正在改变,因为在JS中,当你以这种方式传递一个数组或对象时,你实际上是在传递一个对原来的对象/数组的引用。
这意味着对引用所做的任何更改也将影响原始引用。
为了避免使用引用,您可以复制对象/数组并使用副本。
有几种方法可以做到这一点,最简单的IMO是使用spread syntax。
范例:
我们在这里所做的是将
obj.values
的内容“扩展”到一个新对象中,从而创建一个新对象并避免使用引用。请注意,spread语法只生成一个浅副本,这不一定是一个问题,除非您有一些复杂的对象,其中包含一些其他嵌套对象。
如果确实需要执行深层复制,一种简单的方法是通过
JSON
方法。范例:
qyswt5oh2#
首先,此obj变量不正确,因为per1定义为对象,对象由键和值组成,但它类似于字符串数组,因此请检查,下面是解决方案
在子组件中,您应该创建该obj变量的副本
如果你把inp设置为同一个变量,它会传递那个变量的地址,所以你需要创建一个副本,然后你可以改变inp。