始めに
Reactを勉強していてimmerを使った際にimmutableやmutableという言葉が度々出てきたのでそれらの違いやImmerを使ったミュータブルな値の変更について自分なりにまとめてみました。
参考程度にご覧いただけると嬉しいです。
イミュータブル(immutable)とミュータブル(mutable)の違いについて
イミュータブル(immutable)とミュータブル(mutable)の違いについてご説明します。
イミュータブル(immutable)
イミュータブルは書き換えが不可な値のことを指します。
主に
- 文字列
- 数値
- 真偽値
- undefind
- シンボル
などが該当します。
let val = 0;
val = 1
valという変数に0を代入し下でvalに対して1を代入しています。この時valに1を代入して上書きしているのではなく、参照元が0から1に変わっているだけです。これがimmutableな値。つまり変更不可な値といえます。
ミュータブル(mutable)
ミュータブルな値は書き換えが可能な値になります。
let val = [1,2,3]
val.push(4)
valという変数に配列が格納されているとします。その配列に対してpushメソッドで4を追加したとします。
この時参照先はvalという配列から変わらないため、pushすると配列の元の値も変わることになります。
これがmutableな値。といえます。
これを回避するのにスプレッド演算子を使って新しい配列を取得することも可能ですがImmerを使うと簡単に実装可能なのでご紹介します。
Immerを使ったミュータブルな値の変更
Immerとは?
immutabilityを保持するためのReduxのライブラリとなってます。これにより不変性を維持しながら簡単に状態管理をしやすくなります。
まずはImmerの核となるproduce関数をimportします。
import { produce } from 'immer';
続いてはproduce関数についてご説明します。
produce
まずproduce関数を使って定義します。
import { produce } from 'immer';
const state = {
name: 'りゅうた',
hobbies : ['baseball’ soccer']
}
const newState = produce(state, draft => {
draft.name = 'Tom';
draft.hobbies[0] = 'tennis'
})
console.log(state === newState);//false
stateがオブジェクトになっていてnameプロパティとhobbiesプロパティがあったとしてもhobbiesに関しては配列になっています。
このstateオブジェクトの値をそのままに新しいオブジェクトを生成するためにproduce関数を使います。
書き方としては、
第一引数に初期値
第二引数に変更を加える関数
第二引数であるdraftオブジェクトに加えられた変更をもとに新しい不変な状態を生成します。
上記のコードでは元のオブジェクトのnameをTomに、hobbiesの0番目に’tennis’を代入しています。
produce関数をnewStateに代入しているので、元のstateとnewStateは全く別のオブジェクトだといえます。
まとめ
- Immerは不変データ構造の管理を容易にする
- produce 関数は新しい状態を生成するために使われ、draft は変更を加えるための仮のオブジェクト。
- Redux ToolkitではImmerが内部的に使用され、状態の不変性を自動的に管理する。
最後までご覧いただき、ありがとうございます。
ご不明点やご相談、お仕事の依頼はいつでもお気軽にご連絡ください。
コメント