React性能优化:immutability-helper

项目地址:kolodny/immutability-helperjavascript

轮子做用:以最低的成本对抗浅比较。java

适用场景:state的修改。git

若是使用redux管理数据流,就必然会遇到state的修改。state修改有个特性,redux会进行一次新旧state的浅比较,若是有变更才会触发从新渲染。一个大的项目state的数据结构必然会很复杂,若是有一个很里层的数据被修改,这时就很头疼。github

若是把state深拷贝一次会十分浪费资源,因此咱们不会这么干。浅拷贝一样行不通,由于浅拷贝以后的操做会改变旧的state值,这既不规范,也不会触发渲染。redux

假如咱们有以下一个state:antd

state = {
    info: {
        name: "tom",
        age: 12
    },
    score: {
        exam1: [99, 98, 89],
        exam2: [78, 85]
    }
}
复制代码

进行一次浅拷贝copyState = state,此时的copyStatestate其实保存了相同的值,他们指向内存中的同一片区域。若是如今我进行一番操做:数据结构

state.score.exam2.push(90);
复制代码

对于copyStatestate而言,他们其实没有任何变化,依旧指向同一片内存区域,只是这片区域内保存的数据有了变化,因此此时二者仍然相等。性能

因此浅复制天然也就没法对抗浅比较,并且还可能出现意想不到的反作用(修改state致使copyState也变了)。学习

一个比较原始地方法就是把state照抄一遍,并进行所需的修改:spa

newState = {
    info: state.info,
    score: {
        exam1: state.score.exam1,
        exam2: [
            state.score.exam2[0], 
            state.score.exam2[1], 
            90
        ],
    },
}
复制代码

这就是最大程度上利用原有数据,在不深拷贝的状况下定向修改数据,而且返回一个新对象的操做。

可是上面的操做明显就很笨拙,在ES6引入了...操做符之后,这个操做就能够获得简化:

newState = {
    ...state,
    score: {
        ...state.score,
        exam2: [
            ...state.score.exam2, 
            90,
        ],
    },
}
复制代码

可是能够想象,在数据层级比较深的时候就会写得很复杂,上面的...state.score.exam2已是不短的一串代码了。

面对着这种困境,immutability-helper就是一个与使用...操做逻辑相同,可是书写要简便不少的轮子。这个轮子有必定的学习成本。上面的例子使用immutability-helper实现的具体操做以下:

import update from 'immutability-helper';

newState = update(state, {
    score: {
        exam2: {
            $push: [90]
        }
    }
})
复制代码

不难看出,用了immutability-helper之后少写了不少没必要要的代码,immutability-helper实现的功能还不单单只是这些,有兴趣能够自行研究一下源码。它也是一个被antd推荐使用的轮子。

总而言之,十分推荐在React中使用immutability-helper来进行state的更新,兼具性能与优雅。

相关文章
相关标签/搜索