immutable data

爲何存在Immutable data

JavaScript 中的對象通常是可變的,由於使用了引用賦值,新的對象簡單的引用了原始對象,改變新的對象將影響到原始對象。
例:
圖片描述react

當你打印原始的A時,你會發現
圖片描述dom

雖然這樣作能夠節約內存,但當應用複雜後,數據會變得很很差操控。爲了解決這個問題,通常的作法是使用淺拷貝或深拷貝來避免被修改,但這樣會形成內存的浪費。性能

什麼是Immutable data

Immutable Data就是一旦建立,就不能再被更改的數據。對Immutable對象的任何增刪改操做都會返回一個新的 對象,且舊對象不變。Immutable能夠很好的避免深拷貝遍歷節點帶來的性能損耗,它運用告終構共享原則,即若是對象樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共享。this

淺談immutable React

reacr的淺複製spa

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

...

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

const 就是一次淺複製,一般用於在渲染的時候提供一些變化的值,這樣不須要咱們在render中對某個變量進行其餘操做。因此在明確只是淺複製的狀況下,儘可能使用const定義變量,由於const定義的變量不能被賦值或更改,這樣就能夠避免不當心改變了該變量而引發問題。淺複製的好處就是能夠有效的節約內存地址,避免沒必要要的內存浪費。code

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。blog


react深複製圖片

以前談到的深複製基本是隻能複製一層變量,或者必須嵌套着複製多層變量。若是想要更方便的徹底複製一個對象,咱們可使用如下方法。ip

  1. immutable.js 庫統一解決;
  2. lodash.js
    clone(obj, true) 或cloneDeep(obj)方法
  3. 原生使用JSON.stringify()和parse()方法等
相關文章
相關標籤/搜索