Просто хотел поделиться несколькими советами, которые я подобрал / разработал / адаптировал благодаря своему опыту работы со стеком Typescript React Redux, которые действительно сделали написание правильного кода действительно (б-) легким 🌬.

Добавить универсальный тип для действий

Тип Action, который поставляется с Redux не сразу обеспечивает поддержку типов в полезной нагрузке действия, что является чрезвычайно распространенным вариантом использования.

Это полезная отправная точка для обеспечения общего интерфейса для всех действий в кодовой базе и добавления безопасности типов в полезные данные действий.

Организуйте код Redux по функциям, а не по типу функций

Есть эта забавная человеческая склонность получать удовольствие от объединения одинаковых вещей: объединение всех редукторов в один файл, типов действий в другом и создателей действий в третьем - все это просто так приятно.

Однако такое поведение в конечном итоге укусит нас в проектах Redux, где мы обычно работаем над одной функцией, включающей каждый тип Redux. В итоге у нас одновременно открываются пять разных файлов, каждый из которых на 95% состоит из кода, который совершенно не связан с функцией, над которой мы работаем. Не идеально.

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

Весь связанный код вместе. Мне не нужно тратить дополнительное время на импорт и экспорт переменных друг в друга - все они уже находятся в одном файле. И все мутирует, состояние задачи видно сразу.

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

Воспользуйтесь преимуществами различаемых типов объединения

Эй, говоря о помещении более одного типа действия в файл, давайте посмотрим, как мы можем использовать наш новый причудливый тип Typescript Action, чтобы воспользоваться преимуществами различаемых типов объединения ✨. (Полный код включен для ясности, но прокрутите вниз до редуктора, чтобы увидеть размеченные типы объединения в действии!)

Дискриминированные типы объединения позволяют нам получить сильные Action типы в наших редукторах, что наряду со строгим State типизацией упрощает написание правильных редукторов.

Последовательная организация экспорта Redux

Каждый файл Redux должен экспортировать одни и те же элементы: State, reducer иactions. Сохранение согласованной формы экспорта упрощает повторное использование и объединение файлов Redux.

В качестве примера я добавил функцию «награды», чтобы отслеживать награды за выполнение наших задач 🎂. Вот как будет выглядеть результирующая комбинация функций вознаграждений и задач.

Так выглядит типичный «индексный» файл Redux, который просто объединяет функции Redux. Обратите внимание, что каждая функция todos и rewards имеет согласованный общедоступный API, который полностью отделен от реализации. Функции полностью переносимы.

Эта структура импорта-экспорта работает непрерывно, если вы хотите еще больше вложить свои функции.

Заключение, своего рода

Независимо от того, какие советы вы решите включить в свои собственные методы разработки, имейте в виду, что это всего лишь рекомендации для достижения конечной цели - облегчения написания правильного кода. Возьмите то, что работает, для себя, а то, что не работает, оставьте!

Мысли из толпы?

С чем-то не согласен? Есть идеи по улучшению? У вас есть свои собственные советы и приемы, которые вы нашли при разработке в стеке Typescript-Redux? Дай мне знать в комментариях!

Сноски:

А как насчет селекторов? Это могла бы быть отдельная статья, но я постараюсь высказать здесь несколько кратких мыслей. Тривиальные селекторы не так полезны в проектах Typescript, потому что строгая типизация упрощает изменение состояния и выбор состояния (например, state.foo.bar). Для селекторов, которые инкапсулируют логику, это добавляет дополнительный selectors экспорт к обычному набору, а импортируемый файл Redux должен заключать селекторы в соответствующий ключ состояния.
ОБНОВЛЕНИЕ: Вот суть, которая может вам помочь.

А как насчет саг? Опять же, использование Typescript и redux-saga могло бы стать отдельной статьей, но опять же несколько кратких мыслей. Файл Redux, в котором используются саги, должен иметь дополнительныйsaga экспорт, а импортируемый файл может использовать ту же стратегию для объединения саг, что и комбинирующие редукторы, с использованием fork вместо combineReducers.
ОБНОВЛЕНИЕ: ознакомьтесь с обсуждением здесь для некоторых идей в сочетании саг.