Углубление в асинхронные действия - яркий пример парадокса выбора. Вариантов так много, что сложно понять, с чего начать. Это одна из причин, почему этот пост занял больше времени, чем мои предыдущие посты о React / Redux. Другое дело, что я был в отпуске. :)

@Zackargyle написал краткий обзор

Также доступны:

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

Почему асинхронные действия?

Но давайте вернемся немного назад. Какую проблему мы здесь пытаемся решить?

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

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

Многие руководства по React без Redux, включая React docs, демонстрируют выполнение асинхронных вызовов API в функции componentDidMount (). Вы делаете вызов, и в функции обратного вызова или когда обещание разрешено / отклонено, вы соответствующим образом обновляете локальное состояние компонента. Затем React повторно визуализирует компонент.

Что вы делаете, когда вместо этого хотите управлять этим состоянием в Redux?

Параметры промежуточного программного обеспечения Redux

К счастью, Redux предоставляет очень хороший способ расширить свою функциональность: промежуточное ПО. Промежуточное ПО Redux концептуально такое же, как в Express и многих других фреймворках веб-серверов. Вы создаете конвейер компонентов промежуточного программного обеспечения, каждый из которых имеет возможность воздействовать на все, что проходит через конвейер - в данном случае действия Redux.

Документация Redux предоставляет хорошее пошаговое руководство по созданию промежуточного программного обеспечения для обработки вызовов асинхронного API. К концу этого пошагового руководства вы, по сути, создали промежуточное программное обеспечение redux-thunk.

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

Вы также довольно быстро столкнетесь с большим количеством шаблонного кода в ваших создателях действий. Существует очень распространенный шаблон для обработки большинства вызовов API:

  • Отправьте действие PENDING, чтобы ваш пользовательский интерфейс мог отображать счетчик или другой индикатор того, что вызов выполняется.
  • Сделайте звонок.
  • В функции обратного вызова или решения Promise отправьте действие SUCCEEDED, чтобы ваши редукторы могли обновить свое состояние.
  • Точно так же в обратном вызове ошибки или функции отклонения обещания отправьте действие FAILED, чтобы ваши редукторы могли обновить свое состояние.

Единственные различия между вызовами API, скорее всего, будут заключаться в методе, пути и теле HTTP запроса; а также тип и данные, включенные в действие, которое вы отправляете в случае успеха или неудачи.

Пример из реальной жизни, включенный в репозиторий Redux, показывает, как создать промежуточное ПО, которое обрабатывает этот шаблон за вас. (Если вам нравится, как работает этот пример, вы можете найти его на npm как redux-api-middleware.)

Ключевым шагом в использовании промежуточного программного обеспечения для СУШКИ вашего кода является создание стандартной структуры для ваших объектов действий. Чтобы быть полезным, промежуточное ПО, которое обрабатывает несколько типов действий, должно рассчитывать на то, что они имеют одинаковую структуру. Я уверен, что в этом нет ничего удивительного: вы можете создать свой собственный стандарт или использовать одно из нескольких конкурирующих соглашений, которые возникли. Эти соглашения будут темой моего следующего поста.

Так что я использую?

И теперь я заканчиваю свой пост об асинхронных действиях, даже не сказав, какой подход я использую. Ну, на данный момент я использую redux-thunk и свое собственное промежуточное ПО, которое похоже на redux-api-middleware. Я собираюсь добавить redux-обещание. Мне нравится вид redux-saga, но он довольно сложный, и я хочу подождать, пока мне это действительно понадобится.

Краткая версия заключается в том, что для меня все еще не решено, как обрабатывать асинхронные действия. Я вернусь к этой теме, когда узнаю больше.