BACK
Use casesLocal 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.

script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...