为什么React中nextProps与this.props的取值始终保持一致?
问题根因
你遇到的这个现象是两个常见的React使用错误共同导致的:
- 第一,你修改数组的方式违反了React状态的不可变性原则:
push、splice都是直接修改原数组的可变方法,修改后原数组的内存引用地址不会变化,只是数组内部的内容被修改。当你把修改后的原数组直接传给setState时,React对比新旧状态/属性时会因为引用地址完全相同,认为数据没有发生变化。同时因为原数组已经被你提前修改,this.props.someArray和nextProps.someArray指向的是同一个内存地址的数组,二者的长度当然永远相等。 - 第二,你把控制渲染的判断逻辑写在了
componentWillReceiveProps生命周期中,这个生命周期本身没有控制组件是否渲染的能力,只有返回布尔值的shouldComponentUpdate(nextProps, nextState)才可以通过返回值控制组件是否重渲染。
修正方案
1. 调整数组修改逻辑,遵循不可变原则
每次修改数组时生成全新的数组对象,保证新旧数组引用地址不同:
新增元素场景
// 旧写法(错误,直接修改原数组) // let someArray = this.state.someArray; // someArray.push(this.props.otherArray[index]); // this.setState({ someArray: someArray }); // 新写法(正确,生成新数组) this.setState({ someArray: [...this.state.someArray, this.props.otherArray[index]] })
删除元素场景
// 旧写法(错误,直接修改原数组) // this.state.someArray.splice(index, 1); // this.setState({ someArray: this.state.someArray }); // 新写法(正确,生成新数组) this.setState({ someArray: this.state.someArray.filter((_, i) => i !== index) })
2. 把渲染控制逻辑迁移到正确的生命周期
将判断逻辑放到shouldComponentUpdate中:
shouldComponentUpdate(nextProps) { console.log("someArraylen:" + this.props.someArray.length); console.log("next someArray len:" + nextProps.someArray.length); // 返回true才会触发重渲染 return this.props.someArray.length !== nextProps.someArray.length; }
内容的提问来源于stack exchange,提问作者OwlR
相关产品推荐
相关产品推荐

