javascript - 更改子组件状态会更改父组件 props

标签 javascript reactjs redux immutability

父组件是一个 header

子组件是一个表单,用于在触发 redux 操作的保存后更改 header 中出现的值。

我设置子状态

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

表单用于渲染state.object和修改state.object。 当我修改 state.object 时,父组件的 props 也会改变。

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 存储,而无需分派(dispatch)操作。

希望能找到此问题的解决方案

更新:

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

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

为什么对象扩展运算符没有实现我想要实现的目标?

最佳答案

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

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

state 正在引用 redux 状态对象(如果它是 redux 状态)。所以现在当你使用

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

尽管您会假设您已将对象值克隆到新对象中。然而,Spread 语法仅执行对象的一级副本。

来自Spread Syntax MDN docs :

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 // Now array a is affected as well: [[], [2], [3]]

非常有效

object[key][subkey] = value;

直接在 redux 存储中更改值。

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

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

关于javascript - 更改子组件状态会更改父组件 props,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45317976/

相关文章:

node.js - BrowserRouter 运行错误 - 无效 Hook 调用

javascript - 多个 javascript 文件冲突

javascript - 我有分割屏幕的 javascript 代码,但是,如何从 Flex 应用程序运行它?

javascript - 无法从服务器获取对象数组

javascript - 如何将 ReactJS 应用程序导出为要在其他应用程序中使用的包?

Javascript:无法获得 Promises.all 响应

react-router - 获取异步组件时 React 路由器抛出错误

javascript - 创建后立即自动提交 ReactJS 表单

javascript - 使用 JavaScript 编码莫尔斯电码

javascript - 尝试通过 google Geolocation API 转换经度纬度,但没有成功