Open hysryt opened 2 years ago
イミュータブル(不変)なオブジェクトは効率的な変更検出を可能にする。 イミュータブルなオブジェクトであれば、オブジェクトへの参照が同じということはオブジェクトが同等であることを意味する。 さらに、クローン時には変更されていない箇所を共有することでコピーの処理を安価にする。
Immer によって以下のことが可能になる。
const baseState = [
{
title: "Learn TypeScript",
done: true
},
{
title: "Try Immer",
done: false
}
]
上記のオブジェクトを元に、新しいオブジェクトを追加し、1つ目のオブジェクトのdoneをfalseにしたい。 ただし、baseStateには手を加えず、新しいオブジェクトを作成する。
import produce from "immer"
const nextState = produce(baseState, draft => {
draft[1].done = true
draft.push({title: "Tweet about it"})
})
produce
は必要なコピーを全て行い、第二引数の関数にdraftとして渡す。
npm install immer
<script src="https://unpkg.com/immer"></script>
import { produce } from "immer";
const state = {
count: 0,
};
const newState = produce(state, draft => {
draft.count++;
});
console.log(newState);
$ node script.mjs
{ count: 1 }
produce(currentState, recipe: (draftState) => void): nextState
引数としてベースとなるステートと、ステートに対する変更を行う関数(immerではレシピと呼ぶ)を渡す。 ベースとなるステートはそのまま保たれる。 変更を加えた結果は戻り値として取得できる。
レシピの中では代入など全ての操作が可能。
produceの第一引数に関数(レシピ)を与えると、与えられた状態に対して常に同じ変更を与える関数(producerと呼ぶ)を生成できる。 レシピはdraft以外の引数を取ることができる。 この引数はproducerの引数として渡す。
produce(fn): producer
const incrementer = produce((draft) => {
draft.counter++
});
const state = {
counter: 0,
};
const next = incrementer(state);
const nextnext = incrementer(next);
console.log(nextnext.counter); // 2
https://immerjs.github.io/immer/ Immerはドイツ語で「常に」。 イミュータブルな状態を便利に扱うためのライブラリ。