首先声明本人资质尚浅,本文只用于个人总结。如有错误,欢迎指正、共同提高。
-----------------------------------------------------------------------------------
其实想说的就是,state接收props对象的数据,涉及的值引用问题。
state和props建立赋值关系之后,state变动,对应props的内容也会跟着改变。
这样再应付某些场景的时候,就需要做一些处理:
业务场景: 新旧数据对比
初期方案:
页面初始化查询时,将原始数据保存一份在页面中的state中,然后页面操作页面中的state数据,props中的数据不变。
之后使用props原始数据,和state中改变后的数据进行比对,完成需求。
// 保存原始数据
例: recruits = { text:'1' };
let { recruits } = this.props.data;
this.setState({
inputList: recruits // 保存原始数据至state中
});
// 页面操作,只修改state中的值
this.setState({
inputList: [{ text:'2'}]
});
// 结果
console.log(this.state.inputList.text);
// 2
console.log(this.props.recruits.text);
// 2
总结:
state接收的不是props的数据,而是props的数据引用地址,state修改props会随之改变
问题解决方案( 其实就是值引用问题,涉及深浅copy ):
浅copy就不提了,这里使用的是深copy,但是深copy也是有区别的,就是copy数据的深度(数组or数组对象)
例: [{ text: '1' }, { text: '2' }];
深copy(假): 1、state数组长度变化时, 对应的props不会变动。 2、state数组中的对象变化时, 对应的props会变动
深copy(真): 1、state数组长度变化时,或者数组中的对象变化时, 对应的props都不会变动
let { recruits } = this.props.data;
let newRecruits = [];
if ( recruits && recruits.length>0 ) {
// 深copy (假)
// 1
// newRecruits = recruits.slice();
// 2
// newRecruits = [...recruits];
// 3
// newRecruits = recruits.concat();
// 深copy(真)
newRecruits = JSON.parse(JSON.stringify(recruits));
}
this.setState({
inputList: newRecruits
});