Введение в react-async, пояс служебных программ для декларативного разрешения обещаний и выборки данных

Как вы делаете асинхронные вызовы в React? Вы используете axios, fetch или даже GraphQL?

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

Вы не думали обернуть их индивидуальным крючком?

Все это было выполнено с помощью react-async (react-async), служебный пояс для декларативного разрешения обещаний и выборки данных. Мы собираемся показать вам, насколько легко использовать этот мощный response-async.

Демо с приложением Create React

Как всегда, волшебство начинается с Create React App. Установите response-async с помощью команды npm i react-async. Затем измените src/App.js следующим образом:

Строки с 6 по 10 - это функция выборки. Он вызывается useAsync в строках с 13 по 16.

Этот useAsync деструктурируется тремя элементами: data, error и isPending. Эти элементы используются строками с 21 по 25 для отображения правильного пользовательского интерфейса.

В зависимости от того, находится ли этот вызов в состоянии ожидания, этот вызов приводит к ошибке или этот вызов возвращает данные. Это просто, без необходимости оборачивать побочный эффект на useEffect.

Запустите npm start, вы увидите следующий интерфейс:

Это результат строки 23, так как выборка forhttp://localhost:4000/asset-manifest.json завершилась неудачно.

Вы можете попробовать любой URL-адрес с данными или выполнить следующие действия, чтобы запустить приложение на localhost:4000:

git clone --single-branch --branch chunkOptimization https://github.com/JenniferFuBook/micro-frontend.git
npm i
npm start

Теперь вы увидите результат в строке 24:

Как насчет состояния ожидания в строке 22?

Это немного сложно. Так как это транзитное состояние, вы можете его увидеть или нет.

Установите для своей сети Slow 3G:

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

useAsync Hook

Давайте узнаем о useAsync: это перехватчик, который может использоваться fetch, axios или другими библиотеками для получения данных. Он принимает options и возвращает state.

const state = useAsync(options)

options определены в документации. Мы использовали два из них:

  • promiseFn: функция, которая возвращает обещание, вызывается автоматически.
  • onResolve: обратный вызов вызывается при разрешении обещания.

state свойства определены в документации. Строка 14 разрушила три из них:

  • data: Последнее разрешенное значение обещания, сохраняется при появлении новой ошибки.
  • error: Причина отклоненного обещания, удаляется при поступлении новых данных.
  • _27 _ / _ 28_: Истина, когда обещание в настоящее время ожидает урегулирования.

Мы помещаем оператор console.log в строку 15. Он отображает ‘Resolved’, когда обещание выполнено.

Прервать вызов useAsync

useAsync прерывается. Помимо onResolve есть опция onCancel:

  • onCancel: Обратный вызов вызывается при отмене обещания.

Также есть функция cancel в качестве одного из свойств состояния:

  • cancel: отменяет текущее ожидающее обещание, игнорируя его результат, и вызывает abort() на AbortController.

AbortController - это объект JavaScript, который позволяет при желании прервать один или несколько веб-запросов.

В приведенном выше коде строки с 18 по 20 отменяют вызов выборки. Следовательно, строка 16 выводит ‘Canceled’.

Это встроенный в useAsync способ прервать выполнение обещания. Прерывание также может быть реализовано с помощью следующей функции обещания: fetchManifest.

Второй параметр в строке 6 - это экземпляр AbortController. abortController.signal передается как сигнал в вызов fetch.

У нас есть два console.log звонка. В строке 7 обещание не прерывается. В строке 11 обещание прерывается вызовом в строке 10. Интересно, что этот способ прерывания не запускает onCancel в строке 20 для вывода ‘Canceled’.

Мы добавили оператор debugger в строку 9. Без паузы оба AbortController показывают прерывание как true, поскольку переход от false к true слишком быстр, чтобы console.log мог его уловить.

На следующем снимке экрана показана ошибка прерывания в строке 29.

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

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

useFetch Hook

Если вы используете fetch для получения данных, useFetch Hook может сэкономить несколько строк кода.

Строки с 7 по 10 вызывают useFecth, и состояние деструктурируется с помощью трех элементов: data, error и isPending.

Эти элементы используются строками с 15 по 19 для отображения правильного пользовательского интерфейса. В зависимости от того, находится ли этот вызов в состоянии ожидания, этот вызов приводит к ошибке или этот вызов возвращает данные.

IfPending, IfRejected и IfFulfilled

React-async предоставляет несколько вспомогательных компонентов, которые делают JSX более декларативным и менее загроможденным.

  • IfPending: Выполняется рендеринг только во время выполнения обещания.
  • IfRejected: отображается только в том случае, если обещание отклонено.
  • IfFulfilled: отображается только при выполнении обещания.

Ниже приведен пример этих помощников компонентов:

Посмотрите на строки с 20 по 28, вам кажется, что они чище?

Асинхронный компонент

Компонент <Async> и его помощники состояния могут делать то же самое.

  • Async.Pending: отображается только в то время, когда обещание ожидает выполнения.
  • Async.Rejected: отображается только тогда, когда обещание отклонено.
  • Async.Fulfilled: отображается только при выполнении обещания.

Посмотрите строки с 17 по 25. Вы предпочитаете компонент <Async>? Это полностью зависит от вас.

Заключение

React-async хорошо работает даже в больших приложениях с множественными или вложенными зависимостями данных. Он поощряет загрузку данных по запросу и параллельно на уровне компонентов, а не массово на уровне маршрута или страницы.

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

Спасибо за прочтение. Я надеюсь, что это было полезно. Вы можете увидеть другие мои публикации в Medium здесь.