reactjs setState改变对象引用

yrefmtwq  于 2022-12-03  发布在  React
关注(0)|答案(2)|浏览(136)

我正在从父组件获取对象并将其设置为状态。在子组件中,我正在更新状态,但父引用对象值也会更改,而不仅仅是状态更改。

父组件有一个巨大的对象,

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状态值

对这个有什么想法。

lsmd5eda

lsmd5eda1#

原来的对象正在改变,因为在JS中,当你以这种方式传递一个数组或对象时,你实际上是在传递一个对原来的对象/数组的引用。
这意味着对引用所做的任何更改也将影响原始引用。
为了避免使用引用,您可以复制对象/数组并使用副本。
有几种方法可以做到这一点,最简单的IMO是使用spread syntax

范例:

const ChildComponent = ({obj}) => {
  const [inp, setInp] = useState({...obj.values});
  ...
}

我们在这里所做的是将obj.values的内容“扩展”到一个新对象中,从而创建一个新对象并避免使用引用。
请注意,spread语法只生成一个浅副本,这不一定是一个问题,除非您有一些复杂的对象,其中包含一些其他嵌套对象。
如果确实需要执行深层复制,一种简单的方法是通过JSON方法。

范例:

const clone = JSON.parse(JSON.stringify(original));
qyswt5oh

qyswt5oh2#

首先,此obj变量不正确,因为per1定义为对象,对象由键和值组成,但它类似于字符串数组,因此请检查,下面是解决方案
在子组件中,您应该创建该obj变量的副本

const [inp, setInp] = useState(Object.assign({}, obj.values));

如果你把inp设置为同一个变量,它会传递那个变量的地址,所以你需要创建一个副本,然后你可以改变inp。

相关问题