Уроки44. scan как reducer
Уроки · 44
44. scan как reducer
Reducer pattern
Вместо «чистых» чисел можно использовать actions — объекты, описывающие, что произошло. Это базовая идея Redux/NgRx, и она прекрасно ложится на scan.
actions$.pipe(scan(reducer, initialState))
// reducer(state, action) → newState
Глоссарий
- Action — объект, обычно с полем
type, описывающий событие. - Reducer — чистая функция
(state, action) => newState. - State — текущий «слепок» данных приложения.
Аналогия с NgRx
NgRx устроен по той же схеме: actions через диспатч → reducer → новое состояние → подписчики. Этот урок — компактная учебная версия большого паттерна.
Что нужно сделать
- Внутри reducer проверяйте
action.type: 'increment'→return { count: state.count + 1 }'decrement'→return { count: state.count - 1 }- Иначе верните
stateбез изменений. - Важно: не мутируйте
state— возвращайте новый объект. - Ожидаемый вывод:
Count: 1 → Count: 2 → Count: 1.
Решение spoiler · click to reveal
const { from, scan } = Rx;
const actions$ = from([
{ type: 'increment' },
{ type: 'increment' },
{ type: 'decrement' },
]);
const state$ = actions$.pipe(
scan((state, action) => {
if (action.type === 'increment') {
return { count: state.count + 1 };
}
if (action.type === 'decrement') {
return { count: state.count - 1 };
}
return state;
}, { count: 0 })
);
state$.subscribe(state => console.log('Count: ' + state.count)); script.ts
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...