Обзор на библиотеки
Angular: NgRx
В библиотеке NgRx реализуется принцип работы Redux для Angular приложений.

NgRx предлагает следующую архитектуру организации хранения состояния.
Это единый стор (Store), доступ к частям которого осуществляется посредством селекторов (Selector), при этом компоненту диспатчат экшены (Actions), экшены прослушиваются редьюсерами (Reducer), а редьюсеры обновляют, в свою очередь, стор.


Также есть отдельно стоящие эффекты (Effects), которые также триггерятся экшенами. Эффекты взаимодействуют с сервисами (Services), сервис получает какие-то данные, возвращает в эффекты, а эффекты диспатчат новые экшены, посредством которых через редьюсеры наши данные попадают в стор.
Архитектура многоуровневая, проект программы с NgRx выглядит следующим образом:
Для каждой сущности или набора данных нужно писать свои экшены, свои эффекты, свои редьюсеры, свои селекторы.


Пример кода:
Согласно наиболее правильному подходу, на каждую операцию должно быть описано как минимум 2, а то и 3 экшена. Один — непосредственно на его диспатч, например, на загрузку листа; второй экшен — на успешную его загрузку; третий — на неуспешную загрузку.


Редьюсеры и селекторы пишутся в функциональном стиле в виде экспортируемых констант с помощью функции create, что для angular-разработчика может показаться на первый взгляд непривычно.


Экшен при создании — обычная строка и какие-то данные, если мы хотим эти данные передать посредством экшена. Редьюсеры и селекторы начального состояния создаются с помощью EntityAdapter, который предоставляет удобные функции для работы с коллекциями.


В редьюсер первым параметром передается начальное состояние (например, InitialTodoStatе) и список подписок на экшены. Тут может быть не только Load, Success, но и другие, например, UpdateTodo и так далее.

Для селекторов сначала создается FeatureSelector, это такой небольшой срез всего стейта, чтобы потом от него уже непосредственно брать то, что нам нужно.


Здесь мы через метод Select All из адаптера мы получаем селектор для списка todo:
Эффект оформляется классом, сервисом, каждый эффект представляет собой поле этого сервиса, который тоже создается через функцию createEffect.


Сервис в итоге получается очень чистый – остается только метод получения нашего списка todo, без всяких сайд-эфектов, без лишних сабскрайбов.
Плюсы:

  • максимально чистые компоненты и сервисы

  • высокая популярность библиотеки, потому что она появилась одной из первых

  • наличие множества дополнительных инструментов
Минусы

  • огромное количество бойлерплейта (описывать надо вручную)

  • высокая кривая обучения – чтобы вникнуть в архитектуру, разобраться, как правильно работает библиотека, нужно некоторое время (и оно, пожалуй, самое долгое по сравнению с NGXS и Akita)

  • нет нормального пути получить состояние стора синхронно.
Обзоры других библиотек и финальное сравнение
ищите здесь:

Библиотека Akita
Библиотека NgXs

Что лучше выбрать для работы с Angular —
NGRX, NGXS или Akita?