コンテンツにスキップ

createReducer

Redux パターンに基づいた reducer ベースの状態管理コンテナを作成します。 アクションをディスパッチして reducer 関数に従い状態を更新します。

const [state, dispatch] = createReducer(
(s, action: Readonly<{ type: 'increment' } | { type: 'decrement' }>) => {
switch (action.type) {
case 'increment':
return s + 1;
case 'decrement':
return s - 1;
}
},
0,
);
const stateHistory: number[] = [];
state.subscribe((value: number) => {
stateHistory.push(value);
});
assert.deepStrictEqual(stateHistory, [0]);
dispatch({ type: 'increment' }); // logs: 1
assert.deepStrictEqual(stateHistory, [0, 1]);
dispatch({ type: 'increment' });
dispatch({ type: 'decrement' });
assert.deepStrictEqual(stateHistory, [0, 1, 2, 1]);

等しい更新を伝えない(equals)

Section titled “等しい更新を伝えない(equals)”

第 3 引数で equals オプションを指定できます。

const [count, dispatch] = createReducer(
(s, action: Readonly<{ type: 'add'; amount: number }>) => s + action.amount,
0,
{ equals: () => false },
);
const countHistory: number[] = [];
count.subscribe((value: number) => {
countHistory.push(value);
});
dispatch({ type: 'add', amount: 0 }); // 0 again, passed on all the same
dispatch({ type: 'add', amount: 2 });
assert.deepStrictEqual(countHistory, [0, 0, 2]);

equals は現在の状態と次の状態を受け取ります。true を返すと、その更新は伝わりません。購読者にも、状態から派生したものにも通知されず、現在の状態がその同一性ごと保たれます(dispatch は次の状態ではなく現在の状態を返します)。下流の skipIfNoChange ではなく状態を持つ側で決めるのは、ここで伝わった更新は、オペレーターが間引く前に状態を直接読むものへ届いてしまうためです。

equals の既定値は Object.is で、すでに持っている値を書き込んでも何も伝わりません。等しいかどうかにかかわらずすべての更新を伝えるには equals: () => false を渡してください。

View source on GitHub