更改子组件状态会更改父组件道具 [英] Changing a child components state changes the parent components props

查看:81
本文介绍了更改子组件状态会更改父组件道具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

父组件是标头

子组件是 form ,用于在保存后更改标题中出现的值,该保存会触发redux动作.

Child component is a form which is used to change values appearing in the header after a save which fires a redux action.

我将子状态设置为

constructor(props) {
    super(props);
    this.state = {
      object: { ...props.object },
      hidden: props.hidden,
    };
}

该表单用于呈现state.object并修改state.object. 当我修改state.object时,来自父组件的道具也会发生变化.

The form is used to render the state.object and modify the state.object. When I modify state.object, the props from the parent component change as well.

handleObjectChange = (event, key, subkey) => {
    console.log('props', this.props.object.params);
    console.log('state', this.state.object.params);
    event.preventDefault();
    const value = this.handlePeriod(event.target.value);
    this.setState((prevState) => {
      const object = { ...prevState.object };
      object[key][subkey] = value;
      return { object };
    });
}

控制台输出:

newvalueijusttyped
newvalueijusttyped

实际上,这种行为一直持续到修改redux存储,而无需调度任何动作.

This behavior actually goes all the way up to modifying the redux store without ever having dispatched an action.

将很高兴为此问题提供解决方案

Would appreciate a solution for this issue

更新:

将构造函数更改为此可以解决问题

Changing the constructor to this solved the issue

constructor(props) {
    super(props);
    this.state = {
      object: JSON.parse(JSON.stringify(props.object)),
      hidden: props.hidden,
    };
 }

为什么对象散布运算符不能达到我想要完成的目标?

Why doesn't the object spread operator achieve what I'm trying to accomplish?

推荐答案

JavaScript对象是通过引用分配的,因此在您这样做时

Javascript object are assigned by reference so when you do

constructor(props) {
    super(props);
    this.state = {
      object: props.object,
      hidden: props.hidden,
    };
}

状态引用redux state object(如果它是re​​dux状态).所以现在当您使用

state is referencing the redux state object(if it is a redux state). So now when you use

this.setState((prevState) => {
  const object = { ...prevState.object };
  object[key][subkey] = value;
  return { object };
});

尽管您会假定已将对象值克隆到一个新对象中.但是,Spread语法仅对对象执行一级复制.

Although you would assume that you have cloned the object value into a new object. However Spread syntax does only a one level copy of the object.

传播语法MDN文档 :

From the Spread Syntax MDN docs:

注意:在复制代码时,传播语法有效地深入了一层 大批.因此,它可能不适合复制多维 数组如以下示例所示(与 Object.assign()和传播语法).

Note: Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays as the following example shows (it's the same with Object.assign() and spread syntax).

var a = [ 1 ,[ 2],[3]]; var b = [... a]; b.shift().shift(); //1// 现在数组a也将受到影响:[[],[2],[3]]

var a = [1, [2], [3]]; var b = [...a]; b.shift().shift(); // 1 // Now array a is affected as well: [[], [2], [3]]

非常有效

object[key][subkey] = value;

直接在redux存储区中更改值.

changes the value directly in redux store.

解决方案是创建一个嵌套副本,例如

Solution is create a nested copy like

  const object = { ...prevState.object,
                      [key]: {
                          ...prevState[key],
                          [subkey]: { ...prevState[key][subkey]}
                      }
                   };
  object[key][subkey] = value;

这篇关于更改子组件状态会更改父组件道具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆