Use cases/Local reducer store — scan как мини-store
Use cases · 41 反
Local reducer store — scan как мини-store
Паттерн
У компонента есть список TODO, чекбоксы, wizard со многими шагами — нужна логика add/toggle/remove. Подключать NgRx ради этого — overkill. Делаем мини-store на Subject + scan: actions in → state out.
Какую проблему решаем
Императивные методы add/toggle/remove мутируют поля компонента, легко получить непредсказуемые баги при сложных последовательностях. Тестировать «вот такая цепочка действий приводит к такому состоянию» очень неудобно.
Операторы и зачем они нужны
Subject — принимает actions ({type: 'add', id: 'milk'}).
scan — pure reducer от action и предыдущего state. Это и есть store.
map — derived summary для UI (количество, отфильтрованные items).
shareReplay({ bufferSize: 1, refCount: true }) — кеширует последний state для нескольких подписчиков.
Подводные камни
Reducer ДОЛЖЕН быть чистой функцией. Мутация state in-place ломает OnPush change detection и distinctUntilChanged.
BehaviorSubject с ручными next проще на старте, но scan-store лучше тестируется через marbles и явно фиксирует историю actions.
Для shared cross-route state (корзина, профиль) локальный store узковат — состояние умирает с компонентом.
Что в итоге получаем
State transitions становятся последовательными и тестируемыми. NgRx-подход без NgRx.