我遇到一个奇怪的问题,一个组件正在更新作为道具传递给它的父组件中的变量。
结构看起来像这样:
<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
。有什么办法可以阻止这种情况?用作初始状态的其他道具不会发生此问题,只有作为对象数组的道具才会发生此问题。
答案 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的链接