更改儿童组件中的数据而不在父母中更改它
我正在更改一组数据,并且数据保存在父组件状态下,我将数据传递给第二个组件,但是当我对第二组件中的数据进行更改时,它将在第一个更改数据。 IVE试图为状态的值设置一个变量,以制作IT /还会在第二个组件中创建新状态,该状态是从第一个数据从初始数据设置的。但是由于某种原因,我仍在更改初始数据。谁能解释这里发生了什么?
父组件:
const [data, setData] = useState([]);
const [editing, setEditing] = useState(null);
{!!editing && (
<EditInsurance state={editing} data={data} setEditing={setEditing} />
)}
第二个组件:
const [update, setUpdate] = useState([]);
const [List, setList] = useState([]);
//sets the data onLoad
useEffect(() => {
setList(data);
}, []);
//edits the data
const handleClick = (item) => {
let list = List;
list.forEach((el) => {
if (el.payerName === item.payerName) {
el.state.push(state.value);
if (!el.isActive) {
el.isActive = true;
}
}
});
//update is an array containing only edited objects.
setUpdate([...update, item]);
};
当handleclick
触发时,我会在已更新的父组件中安装data
值。而且我不想更改该数据,直到用户单击保存为止。我如何将数据独有的数据副本不受操纵的数据?
I am making changes to a set of data and the data is held in a parent components state I pass that data to a 2nd component but when I make changes to the data in the 2nd component it is changing the data in the first. Ive tried setting a variable to the value of the state in an effort to make a copy of it / also creating a new state in the 2nd component that is set from the initial data from the first. But For some reason I am still changing the initial data. Can anyone explain whats going on here?
Parent Component:
const [data, setData] = useState([]);
const [editing, setEditing] = useState(null);
{!!editing && (
<EditInsurance state={editing} data={data} setEditing={setEditing} />
)}
2nd Component:
const [update, setUpdate] = useState([]);
const [List, setList] = useState([]);
//sets the data onLoad
useEffect(() => {
setList(data);
}, []);
//edits the data
const handleClick = (item) => {
let list = List;
list.forEach((el) => {
if (el.payerName === item.payerName) {
el.state.push(state.value);
if (!el.isActive) {
el.isActive = true;
}
}
});
//update is an array containing only edited objects.
setUpdate([...update, item]);
};
When handleClick
is fired and I console the data
value in the parent component it has been updated. And I dont want to change that data until the user clicks save. How can I have a copy of the data exclusive to the 2nd component that doesn't manipulate the data in the Parent?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
问题
在这里问题是代码正在突变状态对象。
解决方案
使用/应用不变的更新Patten。任何正在更新的状态都应将其浅入新数组/对象参考。扩展语法是通过引用的浅副本,这就是为什么创建 new array/object参考对于避免突变原始的原因。
我假设这个子组件只需要/需要维护自己的
数据
prop的副本。Issue
The issue here is that the code is mutating the state objects.
Solution
Use/apply the immutable update patten. Any state that is being updated should be shallow copied into to new array/object reference. The spread syntax is a shallow copy by reference, this is why creating new array/object references is necessary to keep from mutating the original.
I'll assume that this child component just wants/needs to maintain its own copy of the
data
prop.您可以尝试使用传播操作员复制列表。在子组件上,您可以执行类似的操作:
然后在子组件上使用parentdata,甚至不需要使用效果。
You can try to copy the list using a spread operator. On the child component, you can do something like:
And then use the parentData on your child component, you don't even need the useEffect.
您需要深层克隆才能保存
handleclick()
的单个对象,可能会缩短到You'll need deep cloning to preserve individual objects in parent
Your
handleClick()
can probably be shortened to我不是很确定,但是您可以尝试类似的东西 -
随着 -
使用 -
这将使您收到的列表道具的克隆副本,现在如果您更改此列表(推送或setstate),则您的父部件将不会反映变化。
现在,在您的Handleclick函数中 - -
在您的子组件渲染方法中使用新清单。
I'm not very sure but you can try something like -
and along with -
use -
This will make a cloned copy of the List props that you received, and now if you change this (push or setState), your parent component will not reflect the changes.
Now in your handleClick function, -
and use newList everywhere in your child component render method.
只需摆脱对props.data的
参考
just get rid of the reference to props.data like so
use lodash's clonedeep/clone method
因此,问题是为什么从子女组件中更改数据的数据?的数据,JS中的对象是参考,
当您执行这样的事情时,
父母的列表和父母的数据是指内存中的同一对象,更改列表中的某些内容将直接反映到数据。好练习。现在,您可以通过在儿童组件中创建新的数据副本来使工作是工作的,
但是随着传播操作员的内在数据,将与儿童组件共享,因此更好的方法是使用JSON.STRINGIFY和JSON.PARSE进行深层副本
。孩子和父母组件都将拥有自己的数据副本,而儿童的更改将不会反映到父母的成分,希望这对您有所帮助。
so the question is why changing data from child component changes data of parent component?,the reason is objects in js are reference,
when you do something like this,
both list of child and data of parent refers to same object in memory,changing something in list will directly reflected to data.and again you are trying to change state of parent component from child directly which is not a good practice. now you can make is work by creating new copy of data in child component, like this
but with spread operator inner nodes of data again will be shared with child component so better way is to make deep copy using JSON.stringify and JSON.parse
this way both child and parent component will have their own copy of data and changes from child will not be reflected to parent component,hope this will help you.
查看其他答案,并且看到您还没有找到解决方案,您是否尝试过克隆
data
在将其传递给Prop之前?父组件:
Looking at the other answers, and seeing as you haven't figured out a solution yet, have you tried cloning
data
before passing it down as a prop?Parent Component: