我的代码如下:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {arr: [{id: 1, val: 11}, {id: 2, val: 22}]}
}
render(){
return (
<div>
<Child Arr = {this.state.arr} />
</div>
)
}
}
class Child extends React.Component {
constructor(props) {
super(props);
this.changeVal = this.changeVal.bind(this)
this.arr = props.Arr
}
changeVal(){
this.arr[0].val *= 2
}
render(){
return (
<div>
<input type='button' value='change val' onClick={this.changeVal} />
</div>
)
}
}
我意识到在按下按钮后,孩子的道具和父母的状态发生了变化。 我以为,当我将道具分配给局部变量时:
this.arr = props.Arr
我可以更改此局部变量,而不会影响其来源的道具或状态。
将传递的prop分配给局部变量时,复制传递的prop是正确的解决方案(下面的代码),还是使用更复杂的状态通常是个坏主意-例如对象等的数组?
class Child extends React.Component {
constructor(props) {
super(props);
this.changeVal = this.changeVal.bind(this)
//this.arr = props.Arr
this.arr = this.copyArrayOfObjects(props.Arr)
}
copyArrayOfObjects(arrToCopy){
if(arrToCopy == null){
return null
}
let arrToRet = []
for(let i=0; i<arrToCopy.length; i++){
let obj = {...arrToCopy[i]}
arrToRet.push(obj)
}
return arrToRet
}
changeVal(){
this.arr[0].val *= 2
}
render(){
return (
<div>
<input type='button' value='change val' onClick={this.changeVal} />
</div>
)
}
}
答案 0 :(得分:1)
this.arr = [...props.Arr]
以上操作并没有真正解决问题,我也不满意对推荐的reactjs(文档)替代解决方案的满意。从一开始,ReactJS就声称状态是私有的,道具是只读的,数据流是一个方向。当它的组件传递给组件时,突然之间,当带有数组的对象作为道具传递时,它的行为很奇怪。这是Reactjs中的设计缺陷。
我使用了lodash(npm i --save lodash
),然后在从父级传递到子级的同时克隆了该对象。它彻底解决了我的问题,应用程序开始按预期运行。
答案 1 :(得分:0)
对象作为参考传递,而不是作为值传递。因此,通过更改child中的值,您最终将在该引用处更改值。
this.arr = props.Arr
将此行更改为
this.arr = [...props.Arr]
如果您的组件完全依赖道具并且您不需要本地状态,那么这值得一读fully controlled component。