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的更新,兼具性能與優雅。

相關文章
相關標籤/搜索