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 を渡してください。