Создатель группы действий NgRx

В этой статье мы рассмотрим новую возможность из пакета @ngrx/store — функцию createActionGroup, которая появилась в версии 13.2.

Использование создателя действия

Обычно мы определяем создателей действий с помощью функции createAction:

// products-page.actions.ts
import { createAction, props } from '@ngrx/store';

// defining an action without payload
export const opened = createAction('[Products Page] Opened');

// defining an action with payload using the `props` function
export const paginationChanged = createAction(
  '[Products Page] Pagination Changed',
  props<{ page: number; offset: number }>()
);

// defining an action with payload using the props factory
export const queryChanged = createAction(
  '[Product Page] Query Changed',
  (query: string) => ({ query })
);
Вход в полноэкранный режим Выход из полноэкранного режима

В этом примере мы используем шаблон «[Источник] Имя события» для определения типов действий, где источником каждого действия является «Страница продуктов». Кроме того, имя создателя каждого действия равно имени события, которое оно выражает. Например, имя создателя действия для события «Pagination Changed» — «paginationChanged».

💡 Если вы не знакомы с обработкой действий как уникальных событий, узнайте больше в этом выступлении Майка Райана.

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

// products.component.ts
import * as ProductsPageActions from './products-page.actions';

@Component({ /* ... */ })
export class ProductsComponent implements OnInit {
  constructor(private readonly store: Store) {}

  ngOnInit(): void {
    this.store.dispatch(ProductsPageActions.opened());
  }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Другой распространенной практикой является создание бочкового файла с именованным экспортом из файлов действий:

// products/actions/index.ts
export * as ProductsPageActions from './products-page.actions';
export * as ProductsApiActions from './products-api.actions';
Войти в полноэкранный режим Выход из полноэкранного режима

Именованные экспорты можно использовать в дальнейшем в файлах, где это необходимо.


Использование создателя группы действий

Функция createActionGroup создает группу создателей действий с одним и тем же источником. В качестве входных аргументов она принимает источник группы действий и словарь событий, где событие — это пара ключ-значение имени события и реквизита события:

// products-page.actions.ts
import { createActionGroup, emptyProps, props } from '@ngrx/store';

export const ProductsPageActions = createActionGroup({
  source: 'Products Page',
  events: {
   // defining an event without payload using the `emptyProps` function
    'Opened': emptyProps(),

    // defining an event with payload using the `props` function
    'Pagination Changed': props<{ page: number; offset: number }>(),

    // defining an event with payload using the props factory
    'Query Changed': (query: string) => ({ query }),
  },
});
Войти в полноэкранный режим Выход из полноэкранного режима

💡 Функция emptyProps является еще одним дополнением к пакету @ngrx/store. Она используется для определения действия без полезной нагрузки в группе действий.

Функция createActionGroup возвращает словарь создателей действий, где имя каждого создателя действия создается с помощью верблюжьей косички имени события, а тип действия создается с помощью шаблона «[Source] Event Name»:

// action type: [Products Page] Opened
ProductsPageActions.opened();

// action type: [Products Page] Pagination Changed
ProductsPageActions.paginationChanged({ page: 10, offset: 100 });

// action type: [Products Page] Query Changed
ProductsPageActions.queryChanged('ngrx');
Вход в полноэкранный режим Выход из полноэкранного режима

Кроме того, больше нет необходимости в бочкообразных файлах или именованном импорте, поскольку группа действий может быть импортирована непосредственно в другой файл:

// products.component.ts
import { ProductsPageActions } from './products-page.actions';

@Component({ /* ... */ })
export class ProductsComponent implements OnInit {
  constructor(private readonly store: Store) {}

  ngOnInit(): void {
    this.store.dispatch(ProductsPageActions.opened());
  }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Если мы создадим новый экшен с помощью функции createAction путем копирования предыдущего, но случайно забудем изменить его тип, компиляция пройдет. К счастью, это не относится к функции createActionGroup — мы получим ошибку компиляции, если два действия из одной группы имеют одинаковый тип.

Ограничения

Мы можем задать разные имена для события и создателя действия с помощью функции createAction:

export const productsLoadedSuccess = createAction(
  '[Products API] Products Are Loaded Successfully',
  props<{ products: Product[] }>()
);
Вход в полноэкранный режим Выйти из полноэкранного режима

В этом примере имя события — «Продукты загружены успешно», а имя создателя действия — «productsLoadedSuccess». К сожалению, это невозможно с помощью функции createActionGroup, потому что имя создателя действия всегда будет равно имени события в верблюжьем регистре. Поэтому для имени события «Продукты загружены успешно» имя создателя действия будет «productsAreLoadedSuccessfully».

Ограничения

Функция createActionGroup позволяет использовать буквы, цифры и пробелы для определения имени события. Некоторые символы, такие как кавычки, круглые скобки или знаки препинания, запрещены. Полный список запрещенных символов доступен здесь.


Заключение

Action group creator улучшает работу разработчиков за счет сокращения кода в файлах действий. Он устраняет необходимость создавать файлы-бочонки или использовать именованный импорт для действий, определять один и тот же источник действия в нескольких местах и дважды писать одно и то же имя для события и создателя действия. Он также обеспечивает хорошую гигиену действий благодаря использованию шаблона «[Источник] Событие» при определении типов действий.

Ресурсы

  • Официальная документация функции createActionGroup

Рецензенты

  • Брэндон Робертс
  • Тим Дешрайвер

Спасибо вам, друзья, за обзор функции createActionGroup PR и полезные предложения по этой статье!

Оцените статью
Procodings.ru
Добавить комментарий