邂逅react(十三) 不可变数据的力量

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 ( 
            
{ this.state.lists.map((item,index)=>{ return(
  • {item.name}---{item.age}
) }) }
); } addListsData(){ let data3={name:'xiaohui',age:22} this.state.lists.push(data3) //直接push原state里面的lists不会引起视图更新 console.log(this.state.lists) } }

如图
邂逅react(十三) 不可变数据的力量_第1张图片

再看另一个场景:

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 ( 
            
{ this.state.lists.map((item,index)=>{ return(
  • {item.name}---{item.age}
) }) }
); } 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渲染页面 }) } }

效果图
邂逅react(十三) 不可变数据的力量_第2张图片
图解小结:
对lists进行push数据虽然发生了改变,但是其内存中存储的url不会发生改变,所以不会触发render对视图进行更新
浅拷贝后的newArr1和lists数据是完全一样的,但是内存地址变了,所以会触发视图更新,我们操作newArr后将它赋值给list,在componentShouldUpdate()周期的时候会比对新旧url,当检测到url变化时会调用render函数,重新渲染我们的视图
看到这里我们就明白啦,直接改state里的引用数据类型根本不会触发视图更新的原因就是它~~~~

你可能感兴趣的:(javascript,react.js)