复制状态以在儿童中间接编辑状态

时间:2018-08-15 21:14:00

标签: javascript reactjs

我在父组件中设置状态,然后将其作为道具传递给子组件。在孩子中,我想复制该状态对象(通过道具接收)以进行编辑,而无需更新原始状态对象。然后,我将在当前子组件中显示该信息,并将更新后的状态对象发送回父对象,以更新原始状态对象。然后,更新后的父状态将用于在其他子元素中显示信息。

在子组件中-其中“ this.props.shifts”是父组件的传递状态:

this.dowCopy = { ...this.props.dow };
this.state = {
    dowCopy: this.dowCopy
}

addTempShift = (day) => {
    const emptyShift = {arbitraryData};
    const dowCopyCopy = {...this.state.dowCopy};
    dowCopyCopy[day].shifts.push(emptyShift);
    this.setState({ dowCopy: dowCopyCopy })
}

一切正常,但是当我在子组件中设置状态时,它也在更新父组件中的状态。据我了解,散布运算符获取了状态对象的副本。我想念什么?

1 个答案:

答案 0 :(得分:1)

传播语法会创建浅拷贝,如@Timothy Wilburn所述。因此,如果您直接更改复制的对象属性,则将对原始对象进行更改。您可以搜索“深度复制”,也可以再次在子组件中使用扩展语法。

class App extends React.Component {
  state = {
    dow: {
      monday: { 
        shifts: [{ name: "foo" }, { name: "bar" }],
      },
    }
  }
  render() {
    return (
    <div>
      In parent: {JSON.stringify(this.state.dow)}
      <Child dow={this.state.dow} />
    </div>
    );
  }
}

class Child extends React.Component {
  state = {
    dowCopy: { ...this.props.dow }
  }

  addTempShift = (day) => {
    const emptyShift = { name: "baz" };
    this.setState( prevState => (
        {
            dowCopy: { ...prevState.dowCopy, [day]: { shifts: 
            [...prevState.dowCopy[day].shifts, emptyShift] } }
        }
    ))
  }

  componentDidMount() {
    this.addTempShift( "monday");
  }

  render() {
    return (
      <div>In Child: { JSON.stringify(this.state.dowCopy)}</div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

哦,男孩。

但是,我同意@George Chanturidze的观点,您过分了。不要复制这样的状态。如果要在Child组件中显示一些已更改的数据,请使用此状态作为其道具来更改它。然后,如果要更改父级的状态,请收集此数据并通过回调发送回父级,然后在其中设置状态。