Перейти к содержанию

Структура кода

Как должна выглядить моя файловая структура? Как я должен группировать генераторы экшенов и редьюсеры в проекте? Где должны быть селекторы?

Поскольку Redux - это просто библиотека хранения данных, у нее нет точного мнения о том, как ваш проект должен быть структурирован. Тем не менее, есть ряд общих паттернов, которые большинство разработчиков Redux склонны использовать:

  • Rails-style: отдельные директории для “экшенов”, “констант”, “редьюсеров”, “контейнеров” и “компонент”
  • Domain-style: отдельные директории для фичи или домена, возможно, с поддиректориями для каждого типа файлов
  • “Ducks”: похож на domain-style, но явно связывающий экшены и редьюсеры, часто определяя их в том же файле

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

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

Документация

Статьи

Обсуждения

Как я должен разделять логику между редьюсерами и генераторами экшенов? Где должна быть "бизнес-логика"?

Нет определенного четкого ответа на то, какие части логики следует переносить в редьюсер, а какие в генератор экшенов. Некоторые разработчики предпочитают иметь "толстые" генераторы экшенов, с "тонкими" редьюсерами, которые просто берут данные в экшене (action) и слепо добавляют их в соответствующее состояние. Другие пытаются подчеркнуть, сохраняя экшенв, как можно маленькими, и свести к минимуму использование getState() в генераторе экшенов. (Для целей данного вопроса, другие асинхронные подходы, такие, как саги и обзерваблы, попадают в категорию "генераторы экшенов")

Есть некоторая потенциальная выгода от использования большего количества логики в ваших редьюсерах. Вероятно, что типы экшенов будут более семантическими и более значимыми (например, «USER_UPDATED» вместо «SET_STATE»). Кроме того, наличие большего количества логики в редьюсеров означает, что больше функциональности будет зависеть от отладки путешествия во времени.

Этот комментарий красиво подводит итог этого разделения:

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

Найти баланс между этими двумя крайностями и вы освоите Redux.

Статьи

Обсуждения

Почему я должен использовать генераторы экшенов?

Redux не требует генераторов экшенов. Вы можете создавать экшены любым удобным для вас способом, включая простую передачу литерала объекта в dispatch. Генераторы экшенов пришли из архитектуры Flux и были приняты сообществом Redux, потому что они предлагают несколько преимуществ.

Генераторы экшенов более поддерживаемы. Обновления экшена могут быть сделаны в одном месте и применены везде. Все экземпляры экшена гарантированно имеют одинаковую форму и одинаковые значения по умолчанию.

Генераторы экшенов тестируемы. Правильность встроенного экшена должна быть проверена вручную. Как и любая функция, тесты для генератора экшена можно написать один раз и запустить автоматически.

Генераторы экшенов легче документировать. Параметры генератора экшена перечисляют зависимости экшена. А централизация определения экшена обеспечивает удобное место для комментариев к документации. Когда экшены записаны в строке, эту информацию сложнее собирать и передавать.

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

Статьи

Обсуждения

Где должны существовать веб-сокеты и другие постоянные соединения?

Мидлвар - это правильное место для постоянных соединений, типа веб-сокетов в Redux приложении, по ряду причин:

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

См. этот пример, который показывает, как мидлвар сокетов может отправлять и реагировать на экшены Redux.

Существует множество мидлваров для веб-сокетов и других подобных соединений: