Redux FAQ: Действия
Содержание
- Почему тип должен быть строкой или хотя бы сериализуемым? Почему мои типы действий должны быть константами?
- Всегда ли существует взаимно-однозначное соответствие между редьюсерами и действиями?
- Как представить «побочные эффекты», такие как вызовы AJAX? Почему нам нужны такие вещи, как «создатели действий», «thunk» и «средства» для асинхронного поведения?
- Должен ли я отправлять несколько действий подряд из одного создателя действий?
Действия
Почему type должен быть строкой или, по крайней мере, сериализуемым? Почему мои типы действий должны быть константами?
Как и в случае с состоянием, сериализуемые действия позволяют использовать ряд определяющих функций Redux, таких как отладка с путешествием во времени, запись и воспроизведение действий. Использование чего-то вроде Symbol для значения type или использование instanceof проверки самих действий нарушит это. Строки сериализуемы и легко самоописательны, поэтому являются лучшим выбором. Обратите внимание, что использование символов, обещаний или других несериализуемых значений в действии допустимо, если действие предназначено для использования средствами. Действия должны быть сериализуемыми только к моменту, когда они фактически попадают в хранилище и передаются редьюсерам.
По причинам производительности мы не можем надежно применять сериализуемые действия, поэтому Redux только проверяет, что каждое действие является простым объектом, и что type определен. Остальное зависит от вас, но вы можете обнаружить, что сохранение всего сериализуемого помогает отлаживать и воспроизводить проблемы.
Инкапсуляция и централизация часто используемых фрагментов кода — ключевой концепцией программирования. Хотя можно вручную создавать объекты действий повсюду и писать каждое значение type вручную, определение повторно используемых констант упрощает поддержку кода. Если вы поместите константы в отдельный файл, вы сможете проверить ваши import заявления на наличие опечаток, чтобы случайно не использовать неправильную строку.
Дополнительная информация
Документация
Обсуждение
- #384: Рекомендация, чтобы имена констант действий были в прошедшем времени
- #628: Решение для создания простых действий с меньшим объемом кода
- #1024: Предложение: декларативные редьюсеры
- #1167: Редьюсер без переключателя
- Stack Overflow: Зачем вам нужны «Действия» как данные в Redux?
- Stack Overflow: В чём смысл констант в Redux?
Всегда ли существует взаимно-однозначное соответствие между редьюсерами и действиями?
Нет. Мы рекомендуем писать независимые небольшие функции редьюсеров, каждая из которых отвечает за обновления конкретного фрагмента состояния. Мы называем этот шаблон «составление редьюсеров». Данное действие может обрабатываться всеми, некоторыми или ни одним из них. Это сохраняет компоненты независимыми от фактических изменений данных, поскольку одно действие может повлиять на разные части дерева состояния, и нет необходимости, чтобы компонент об этом знал. Некоторые пользователи выбирают более тесную связь, например, структуру файлов «уток», но по умолчанию взаимно-однозначного соответствия нет, и вы должны от него отказаться всякий раз, когда захотите обработать действие в нескольких редьюсерах.
Дополнительная информация
Документация
Обсуждения
- Twitter: самое распространенное заблуждение Redux
- #1167: Редьюсер без переключателя
- Reduxible #8: Редьюсеры и создатели действий не имеют взаимно-однозначного соответствия
- Stack Overflow: Могу ли я отправить несколько действий без промежуточного слоя Redux Thunk?
Как представить «побочные эффекты», такие как вызовы AJAX? Почему нам нужны такие вещи, как «создатели действий», «thunk» и «средства» для асинхронного поведения?
Это длинная и сложная тема с широким спектром мнений о том, как следует организовывать код и какие подходы следует использовать.
Любой значимый веб-приложение должен выполнять сложную логику, обычно включающую асинхронную работу, такую как выполнение запросов AJAX. Этот код больше не является чисто функцией своих входов, а взаимодействия с внешним миром известны как «побочные эффекты».
Redux вдохновлён функциональным программированием и по умолчанию не предусматривает выполнение побочных эффектов. В частности, функции редьюсеров *должны* всегда быть чистыми функциями от (state, action) => newState. Однако средства Redux позволяют перехватывать отправленные действия и добавлять дополнительное сложное поведение вокруг них, включая побочные эффекты.
В общем, Redux предполагает, что код с побочными эффектами должен быть частью процесса создания действия. Хотя эту логику *можно* выполнить внутри компонента пользовательского интерфейса, обычно имеет смысл извлечь эту логику в переиспользуемую функцию, чтобы ту же логику можно было вызывать из нескольких мест — другими словами, функцию-создателя действий.
Самый простой и распространённый способ — добавить промежуточный слой Redux Thunk, который позволяет вам создавать создатели действий с более сложной и асинхронной логикой. Другой широко используемый метод — Redux Saga, который позволяет писать код, более похожий на синхронный, с использованием генераторов и может действовать как «фоновые потоки» или «демоны» в приложении Redux. Ещё один подход — Redux Loop, который инвертирует процесс, позволяя вашим редьюсерам объявлять побочные эффекты в ответ на изменения состояния и выполнять их отдельно. Помимо этого, существуют *многие* другие разработанные сообществом библиотеки и идеи, каждая со своим взглядом на то, как должны управляться побочные эффекты.
Дополнительная информация
Документация
Статьи
- Побочные эффекты Redux и вы
- Чистая функциональность и побочные эффекты в Redux
- От Flux к Redux: асинхронные действия простым способом
- React/Redux Ссылки: категория «Побочные эффекты Redux»
- Gist: Примеры Redux-Thunk
Обсуждения
- #291: Попытка поместить вызовы API в нужное место
- #455: Моделирование побочных эффектов
- #533: Более простое введение в создателей асинхронных действий
- #569: Предложение: API для явных побочных эффектов
- #1139: Альтернативная модель побочных эффектов, основанная на генераторах и сагах
- Stack Overflow: Почему нам нужны средства для асинхронного потока в Redux?
- Stack Overflow: Как отправить действие Redux с таймаутом?
- Stack Overflow: Где следует разместить синхронные побочные эффекты, связанные с действиями, в Redux?
- Stack Overflow: Как обрабатывать сложные побочные эффекты в Redux?
- Stack Overflow: Как протестировать асинхронные действия Redux, чтобы смоделировать ответ AJAX
- Stack Overflow: Как запускать вызовы AJAX в ответ на изменения состояния с Redux?
- Reddit: Помощь в выполнении асинхронных вызовов API с Redux-Promise Middleware.
- Twitter: возможное сравнение между сагами, циклами и другими подходами
Должен ли я отправлять несколько действий подряд из одного создателя действий?
Нет конкрельных правил для структурирования ваших действий. Использование асинхронного промежуточного слоя, такого как Redux Thunk, определённо позволяет создавать сценарии, такие как отправка нескольких различных, но взаимосвязанных действий подряд, отправка действий для отображения прогресса запроса AJAX, отправка действий условно на основе состояния или даже отправка действия и проверка обновлённого состояния сразу после этого.
В общем, спросите себя, эти действия связаны, но независимы, или их следует представить как одно действие. Делайте то, что имеет смысл для вашей ситуации, но старайтесь уравновесить читаемость редьюсеров с читаемостью журнала действий. Например, действие, включающее всё новое дерево состояния, сделает ваш редьюсер однострочным, но недостатком является отсутствие истории *почему* происходят изменения, поэтому отладка становится очень сложной. С другой стороны, если вы отправляете действия циклически, чтобы сохранить их гранулярность, это означает, что вы можете ввести новый тип действия, который обрабатывается другим способом.
Старайтесь избегать многократного синхронного отправления в тех местах, где вы беспокоитесь о производительности. Есть ряд дополнений и подходов, которые могут объединять отправления.
Дополнительная информация
Документация
Обсуждения
- #597: Разрешено ли отправлять несколько действий из обработчика событий?
- #959: Несколько действий в одном отправлении?
- Stack Overflow: Следует ли использовать один или несколько типов действий для представления этого асинхронного действия?
- Stack Overflow: Имеют ли события и действия отношение 1:1 в Redux?
- Stack Overflow: Должны ли действия обрабатываться редьюсерами, связанными с действиями, или генерироваться самими создателями действий?
© 2015–2017 Dan Abramov
Licensed under the MIT License.
http://redux.js.org/docs/faq/Actions.html