首页 文章

更改子组件状态会更改父组件道具

提问于
浏览 1023 次
2

父组件是 Headers

子组件是一种形式,用于更改在触发redux操作的保存之后出现在 Headers 中的值 .

我设置了子状态

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存储而没有调度动作 .

非常感谢这个问题的解决方案

Update:

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

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

为什么对象传播运算符不能实现我想要实现的目标?

2 回答

  • 1

    Javascript对象是通过引用分配的,所以当你这样做时

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

    state正在引用 redux state object (如果它是redux状态) . 所以现在你用的时候

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

    虽然您可以假设已将对象值克隆到新对象中 . 但是,Spread语法只对该对象的一级副本 .

    来自 Spread Syntax MDN docs

    注意:在复制数组时,扩展语法有效地达到一个深度 . 因此,它可能不适合复制多维数组,如下例所示(它与Object.assign()和spread语法相同) . var a = [1,[2],[3]]; var b = [... a]; . b.shift()移位(); // 1 //现在数组a也受到影响:[[],[2],[3]]

    如此有效

    object[key][subkey] = value;
    

    直接在redux store中更改值 .

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

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

    javascript中的对象是“通过引用传递” .

    如果您将父级的道具作为状态传递给子级,那么当您更改状态时,实际上是在改变传递给它的同一个对象 .

    在将数据作为子状态的一部分之前,使用Object.assign()创建数据的克隆 .

相关问题