reduxのstateはイミュータブルだけどイミュータブルじゃない

備忘録

reduxのstateはイミュータブル

reduxが保持している状態はイミュータブルなオブジェクトとして扱われるため、
直接変更することができない。
そのため、stateを変更したい場合には下記のようなコードによって、新しいオブジェクトを作る処理が必要になる。

case ADD_ITEM :
    return { 
        ...state,
        arr: [...state.arr, action.newItem]
    }

参考 stackoverflow.com

stateがイミュータブルではなくなる場合

reduxのstateはオブジェクト内のプロパティを操作する場合には、直接変更することができる。

case SPLICE_ITEM :
    state.arr.splice(1, 1); // エラーが発生しない

原因

redux.js.org

reduxは浅い参照でstateの変更を検知している。
仮にstate.arr = newArrのような処理があった場合には、オブジェクトの参照先メモリが変更されるため、
reduxはエラーを検知することができるが、state.arr.splice(1, 1)のようにオブジェクト内のプロパティの操作は、
浅い参照では検知することができない。

reduxに検知されないstateの変更はstateを使用しているコンポーネントの更新も行われないため、非常に危険。