- 投稿日:2019-05-29T12:52:29+09:00
ImmerjsでRedux周りをスッキリさせたい
前提
- react,reduxでフロント開発中 - 「Immerjs便利」とすすめられる - 「そもそもイミュータブルってなんだ?」使うライブラリ:GitHub - immerjs/immer: Create the next immutable state by mutating the current one
そもそもイミュータブルとは
- 「イミュータブル(immutable)」
- 不変、変わらない
- プログラミングにおいて「イミュータブル」とは?
- オブジェクトの状態が変更されないこと
- redux等はイミュータブルを実現してる
const array = { test1: '国語', test2: '理科', test3: '算数', } console.log({array}); // ミュータブル // arrayの値が変わってしまう array['test1'] = '英語'; console.log({array}); // イミュータブル // arrayの値は変えず、新しいオブジェクトを生成する const array2 = {...array, test1:'英語'}; console.log({array2});
- いいところ
- 参考:Immutableとはなんぞや?なにが嬉しいの? - Panda Noir
- オブジェクトが変更されないので、予測が付きやすい
- 新しいオブジェクトを生成するとき、差分のみ保持して、あとは元のオブジェクトを参照するので省メモリ
Immerjs導入
- 導入にあたって
- 上述のイミュータブルのいいところは既にReduxがやってくれてる
- 期待するのは、記述の簡素化
- スプレッド演算子があんまり好きじゃない
newState={...state, todo1: 'マヨネーズ買う'}
- 一回くらいならいいけど、reducerは
...state
ばっかになる。コード見づらい- オブジェクトの階層が深くなると分かりづらくなる
サンプルコード
GitHub - immerjs/immer:より引用です。
↓ Reduxデフォの書き方
// Redux reducer // Shortened, based on: https://github.com/reactjs/redux/blob/master/examples/shopping-cart/src/reducers/products.js const byId = (state, action) => { switch (action.type) { case RECEIVE_PRODUCTS: return { ...state, ...action.products.reduce((obj, product) => { obj[product.id] = product return obj }, {}) } default: return state } }↓ immerjs使った場合
import produce from "immer" const byId = (state, action) => produce(state, draft => { switch (action.type) { case RECEIVE_PRODUCTS: action.products.forEach(product => { draft[product.id] = product }) } })導入した感想
- reducerがスッキリした
- スプレッド演算子なくって万歳
- draftという単語に慣れない
- 別の命名も思いつかない
- 慣れの問題だと思うので使い続ける
- 次はimmerjs/use-immerも使ってみる
useState
だとprevState
を取得するのにuseEffect
使わなきゃいかんが、これなら楽そう