immutable data

为什么存在Immutable data

JavaScript 中的对象一般是可变的,因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。
例:
图片描述

当你打印原始的A时,你会发现
图片描述

虽然这样做可以节约内存,但当应用复杂后,数据会变得很不好操控。为了解决这个问题,一般的做法是使用浅拷贝或深拷贝来避免被修改,但这样会造成内存的浪费。

什么是Immutable data

Immutable Data就是一旦创建,就不能再被更改的数据。对Immutable对象的任何增删改操作都会返回一个新的 对象,且旧对象不变。Immutable可以很好的避免深拷贝遍历节点带来的性能损耗,它运用了结构共享原则,即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

浅谈immutable React

reacr的浅复制

this.state = {
    label : 1,
    value : "ccc"
}

...

render(
    const { label, value } = this.state;
    return(
        <div>
            label: { label }, value: { value }
        </div>
    )
)

const 就是一次浅复制,通常用于在渲染的时候提供一些变化的值,这样不需要我们在render中对某个变量进行其他操作。所以在明确只是浅复制的情况下,尽量使用const定义变量,因为const定义的变量不能被赋值或更改,这样就可以避免不小心改变了该变量而引起问题。浅复制的好处就是可以有效的节约内存地址,避免不必要的内存浪费。

this.state = {
    value: { a: 1 }
}
const { value } = this.state;//浅复制
value.a = 2;
console.log(this.state.value.a);//输出2,但dom不更新
this.setState({ value });//dom更新

这里 value.a = 2 虽然已经改变了state中value的值,但由于是浅复制,新旧value指向的是同一块内存地址,组件更新时(state,props改变)默认只比较新旧对象的内存地址是否一致,如果一致则不更新。同理,如果在reducer中,直接对当前的state进行修改并返回props,相应的调用该props的组件不会更新渲染。

const initialState = {
    count: 1
}
function reducer(state = initialState, action){
    switch(action.type){
        case ADD_COUNT:
        state.count += 1;
        return { ...state }; //state改变,用到该state的组件不更新渲染
        default:
        return state;
    }
}

基于组件更新的原理,即比较新旧state或props是否指向同一块内存地址,如果是则不更新,如果不是则更新。也就是说就算是两个对象的值相等但不指向同一地址,dom也会重新渲染。这并不是我们想要看到的,我们需要的是当props的值改变的时候dom重新渲染。我们可以在shouldComponentUpdate()方法里面定义dom是否更新的条件,如 if ( props === nextProps ) return true。


react深复制

之前谈到的深复制基本是只能复制一层变量,或者必须嵌套着复制多层变量。如果想要更方便的完全复制一个对象,我们可以使用以下方法。

  1. immutable.js 库统一解决;
  2. lodash.js
    clone(obj, true) 或cloneDeep(obj)方法
  3. 原生使用JSON.stringify()和parse()方法等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值