Reactjs:如何防止孩子修改道具?

时间:2019-02-12 01:09:13

标签: javascript reactjs

我遇到一个奇怪的问题,一个组件正在更新作为道具传递给它的父组件中的变量。

结构看起来像这样:

<configuration>
        <property>
      <name>hbase.rootdir</name>
      <value>hdfs://localhost:9000/hbase</value>
   </property>

   <property>
      <name>hbase.zookeeper.property.dataDir</name>
      <value>/home/bithu/hbase-temp</value>
   </property>

  <property>
      <name>hbase.master.port</name>
      <value>7000</value>
   </property>

    <property>
      <name>hbase.regionserver.port</name>
      <value>7010</value>
   </property>

   <property>
      <name>hbase.tmp.dir</name>
      <value>/home/bithu/hbase-temp/tmp</value>
   </property>

<property>
  <name>hbase.unsafe.stream.capability.enforce</name>
  <value>false</value>
</property>
   <property>
     <name>hbase.cluster.distributed</name>
     <value>true</value>
   </property>
</configuration>

调用class ParentComponent extends Component { const toPassToChild = [{ name: 'name', val: 0 }]; ... render() { return(<ChildComponent p={toPassToChild} />); } } class ChildComponent extends Component { constructor(props) { this.state = { ... arrayOfObjects: this.props.p } } modifyState() { let aCopy = [...this.state.arrayOfObjects]; let member = aCopy.find(element => { return element.name === 'name'; }); member.name = 'foo'; this.setState({ arrayOfObjects: aCopy )}; } } 时,modifyState()的值在toPassToChild中更改为ParentComponent。有什么办法可以阻止这种情况?用作初始状态的其他道具不会发生此问题,只有作为对象数组的道具才会发生此问题。

2 个答案:

答案 0 :(得分:0)

member.name中修改modifyState时,您是在对原始对象进行突变,因为[...this.state.arrayOfObjects]仍包含对原始对象的引用。

以下是在不更改原始内容的情况下更新数组的方法:

modifyState() {
  const arrayOfObjects = this.state.arrayOfObjects.map(obj => {
    if (obj.name === 'name') {
      return { ...obj, name: 'foo' };
    }
    return obj;
  });

  this.setState({ arrayOfObjects });
}

答案 1 :(得分:0)

我已经更改了您在子组件中复制的方式。 [...]仅复制第一级元素。

class ParentComponent extends Component {
  const toPassToChild = [{ name: 'name', val: 0 }];
  ...

  render() {
    return(<ChildComponent p={toPassToChild} />);
  }
}

class ChildComponent extends Component {
  constructor(props) {
    this.state = {
      ...
      arrayOfObjects: this.props.p
    }
  }

  modifyState() {
    let aCopy = JSON.parse(JSON.stringify(this.state.arrayOfObjects));

    let member = aCopy.find(element => {
      return element.name === 'name';
    });

    member.name = 'foo';

    this.setState({
      arrayOfObjects: aCopy
    )};
  }
}

检查工作版本为https://stackblitz.com/edit/react-kxtvoi?file=index.js的链接