React中赋值props到组件变量后修改变量引发props变更问题
问题原因与解决方案
嘿,这个问题我之前开发React时也踩过一模一样的坑!咱们一步步拆解清楚:
为什么props会被意外修改?
核心原因是JavaScript中引用类型的赋值是「传引用」而非「传值」。
你父组件传的prova是数组,属于引用类型。当你在子组件构造函数里执行:
this.categories1 = this.props.categories;
这行代码并没有创建一个新数组,而是让this.categories1和this.props.categories指向了内存里同一个数组对象。
而你接下来调用的splice方法,是数组的原地修改方法——它会直接改变调用它的原数组,不会返回新数组。所以当你执行this.categories1.splice(...)时,本质上是修改了this.props.categories指向的那个数组(也就是父组件里的prova),这就导致两次console.warn输出的结果完全不一样。
怎么解决这个问题?
思路很简单:先复制出一个独立的新数组,再对新数组操作,切断和原props的引用关联。
方案1:浅拷贝(适用于数组元素是基础类型或不需要修改元素内部的场景)
你可以用以下几种方式快速复制数组:
- 扩展运算符:
[...this.props.categories] Array.from():Array.from(this.props.categories)slice():this.props.categories.slice()(不传参数时会返回原数组的浅拷贝)
修改后的子组件代码:
class ScrollHorizontalTwoColumns extends React.Component { categories1 = ""; categories2 = ""; constructor(props) { super(props); console.warn(this.props.categories); if (typeof this.props.categories === 'object' && this.props.categories.length > 0){ // 先浅拷贝出一个新数组,切断和props的引用关联 this.categories1 = [...this.props.categories]; // 现在操作的是新数组,不会影响原props this.categories2 = this.categories1.splice(0, Math.ceil(this.categories1.length / 2)) } console.warn(this.props.categories); } }
方案2:深拷贝(如果数组元素是对象,且需要修改对象内部属性时)
如果你的数组元素是复杂对象(比如例子里的{1: 'a'}),并且之后需要修改这些对象的属性,那浅拷贝还不够——因为浅拷贝只会复制数组的引用,数组里的对象还是和原props里的对象指向同一个内存地址。这时候需要用深拷贝:
// 用JSON序列化/反序列化实现深拷贝(注意:不适用于包含函数、Symbol等特殊类型的对象) this.categories1 = JSON.parse(JSON.stringify(this.props.categories));
如果项目里引入了Lodash库,也可以用_.cloneDeep(this.props.categories)来实现更可靠的深拷贝。
内容的提问来源于stack exchange,提问作者Cookie
相关产品推荐
相关产品推荐

