react中 state的数据不可变原则,为什么这么设计呢?
因为react的生命周期中每次调用ComponentShouldUpdate()会将state现有的数据跟将要改变的数据进行比较,更新发生变化的数据,最大限度减少不必要的更新,达到性能的优化。所以不建议直接更改state里面的数据,而是通过setState去改变
关于state中直接改变引用类型数据,视图无法更新的问题
小案例1
class TheState extends Component {
constructor(props){
super(props)
this.state={
lists:[
{name:'dabai',age:18},
{name:'xhh',age:20},
{name:'ali',age:25}
],
num:0
}
}
render() {
return (
<div>
{
this.state.lists.map((item,index)=>{
return(
<ul key={item+index}>
<li>
{item.name}---{item.age}
</li>
</ul>
)
})
}
<button onClick={this.addListsData.bind(this)}>添加数据</button>
</div>
);
}
addListsData(){
let data3={name:'xiaohui',age:22}
this.state.lists.push(data3) //直接push原state里面的lists不会引起视图更新
console.log(this.state.lists)
}
}
如图
再看另一个场景:
class TheState extends Component {
constructor(props){
super(props)
this.state={
lists:[
{name:'dabai',age:18},
{name:'xhh',age:20},
{name:'ali',age:25}
]
}
}
render() {
return (
<div>
{
this.state.lists.map((item,index)=>{
return(
<ul key={item+index}>
<li>
{item.name}---{item.age}
<button
onClick={this.addAge.bind(this,index)}
style={{marginLeft:'20px'}}>增加年龄
</button>
</li>
</ul>
)
})
}
<button onClick={this.addListsData.bind(this)}>添加数据</button>
</div>
);
}
addListsData(){
let data3={name:'xiaohui',age:22}
let newArr1=[...this.state.lists]//浅拷贝一份数据
newArr1.push(data3) //往拷贝的数组里push数据
console.log(newArr1)
this.setState({
lists:newArr1 //将改变后的数据重新赋值给原有的对象 这时react内部会调用render刷新数据
})
//**** 注意 直接push原state里面的lists不会引起视图更新 稍后图解 */
}
addAge(index){
let newArr2=[...this.state.lists]//浅拷贝一份数据
newArr2[index].age+=1 //修改拷贝后的数据
this.setState({
lists:newArr2 //重新赋值 调用render渲染页面
})
}
}
效果图
下面是图解
图解小结:
对lists进行push数据虽然发生了改变,但是其内存中存储的url不会发生改变,所以不会触发render对视图进行更新
浅拷贝后的newArr1和lists数据是完全一样的,但是内存地址变了,所以会触发视图更新,我们操作newArr后将它赋值给list,在componentShouldUpdate()周期的时候会比对新旧url,当检测到url变化时会调用render函数,重新渲染我们的视图
看到这里我们就明白啦,直接改state里的引用数据类型根本不会触发视图更新的原因就是它~~~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。