前提
- 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
- オブジェクトが変更されないので、予測が付きやすい
- 新しいオブジェクトを生成するとき、差分のみ保持して、あとは元のオブジェクトを参照するので省メモリ
- 参考: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
使わなきゃいかんが、これなら楽そう
-