Декларативная выборка данных с React Async

0 255

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

Введение в React-Async

React Async — это библиотека на основе промисов, которая предлагает декларативный API для выполнения вызовов API. Она предоставляет компонент React и хук для декларативного разрешения промисов и выборки данных.

React Async совместим практически со всеми библиотеками и API для извлечения данных, включая Fetch API, Axios и GraphQL. Кроме того, он также хорошо работает с React Native.

Установка React Async

Установить библиотеку React Async довольно просто. Вы можете обращаться с ней как с любой другой библиотекой JavaScript и устанавливать ее с помощью NPM или Yarn.

Декларативная выборка данных с React Async

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

JavaScript //NPM npm install — save react-async //Yarn yarn add react-async

12345 //NPMnpm install — save react-async //Yarnyarn add react-async

У нее более 33 тысяч загрузок в неделю и 2 тысячи звезд на GitHub.

Примечание: не забудьте установить React как зависимость для этого пакета. Вам понадобится react @16.8.0 или выше, если вы хотите использовать хук useAsync.

Основы React Async

React Async — простая библиотека. Для начала вам необходимо ознакомиться с тремя основными API:

Компонент Async.

Хук useAsync.

Функция createInstance.

Итак, давайте подробно рассмотрим, что это за API и как они используются.

1. Компонент Async

Компонент Async — это классический интерфейс React Async, и мы можем использовать его, чтобы сделать компоненты React более декларативными. Мы можем напрямую использовать компонент Async в JSX для применения паттерна props. Ниже приведен простой пример использования компонента Async для получения данных.

JavaScript import React, { Component } from «react»; import ReactDOM from «react-dom»; import «./styles.css»; import Async from «react-async»; const loadUsers = () => fetch(«https://jsonplaceholder.typicode.com/users») .then(res => (res.ok ? res : Promise.reject(res))) .then(res => res.json()); const App = () => ( <Async promiseFn={loadUsers}> {({ data, error, isLoading }) => { if (isLoading) return «Loading…»; if (error) return `Something went wrong: ${error.message}`; if (data) return ( <div> <h2>React Async — Users</h2> {data.map(el => ( <li> {el.name} — {el.email} </li> ))} </div> ); return null; }} </Async> ); const rootElement = document.getElementById(«root»); ReactDOM.render(<App />, rootElement);

123456789101112131415161718192021222324252627282930313233 import React, { Component } from «react»;import ReactDOM from «react-dom»;import «./styles.css»;import Async from «react-async»; const loadUsers = () =>  fetch(«https://jsonplaceholder.typicode.com/users»)    .then(res => (res.ok ? res : Promise.reject(res)))    .then(res => res.json()); const App = () => (  <Async promiseFn={loadUsers}>    {({ data, error, isLoading }) => {      if (isLoading) return «Loading…»;      if (error) return `Something went wrong: ${error.message}`;      if (data)        return (          <div>            <h2>React Async — Users</h2>            {data.map(el => (              <li>                {el.name} — {el.email}              </li>            ))}          </div>        );      return null;    }}  </Async>); const rootElement = document.getElementById(«root»);ReactDOM.render(<App />, rootElement);

В приведенном выше примере fetch API используется для выполнения вызова API внутри функции loadUsers. Он возвращает промис. И мы можем получить доступ к props из возвращаемых параметров промиса. Рrops выглядят следующим образом:

data: запрошенные данные с сервера.

error: для случаев, когда возникает ошибка.

isLoading: для сценариев, в которых ответ сервера еще не завершен.

С React Async нам не нужно использовать классы или методы жизненного цикла для извлечения данных и не нужно указывать, как обрабатывать данные.

2. Хук useAsync

Хук useAsync позволяет использовать базовые функции React Async непосредственно в функциональных компонентах. Если вам нравится использовать React Hooks, вы можете использовать useAsync Hook вместо компонента Async. В приведенном ниже примере показано, как мы можем использовать хук useAsync для извлечения данных.

JavaScript import React from «react»; import ReactDOM from «react-dom»; import «./styles.css»; import { useAsync } from «react-async» const loadUsers = () => fetch(«https://jsonplaceholder.typicode.com/users») .then(res => (res.ok ? res : Promise.reject(res))) .then(res => res.json()); const App = () => { const { data, error, isPending } = useAsync({ promiseFn: loadUsers, userId: 1 }) if (isPending) return «Loading…» if (error) return `Something went wrong: ${error.message}` if (data) return ( <div> <h2>React Async — Users</h2> {data.map(el => ( <li> {el.name} — {el.email} </li> ))} </div> ) return null } const rootElement = document.getElementById(«root»); ReactDOM.render(<App />, rootElement);

123456789101112131415161718192021222324252627282930 import React from «react»;import ReactDOM from «react-dom»;import «./styles.css»;import { useAsync } from «react-async» const loadUsers = () =>  fetch(«https://jsonplaceholder.typicode.com/users»)    .then(res => (res.ok ? res : Promise.reject(res)))    .then(res => res.json()); const App = () => {  const { data, error, isPending } = useAsync({ promiseFn: loadUsers, userId: 1 })  if (isPending) return «Loading…»  if (error) return `Something went wrong: ${error.message}`  if (data)    return (      <div>            <h2>React Async — Users</h2>            {data.map(el => (              <li>                {el.name} — {el.email}              </li>            ))}          </div>    )  return null} const rootElement = document.getElementById(«root»);ReactDOM.render(<App />, rootElement);

Как видите, я передал метод загрузки данных loadUsers в useAsync Hook. И вы можете получить доступ к результату, ошибкам или статусу с помощью props. Библиотека также предлагает еще один хук под названием useFetch, предназначенный для использования с Fetch API.

JavaScript import { useFetch } from «react-async» const AppComponent = () => { const headers = { Accept: «application/json» } const { data, error, isPending, run } = useFetch(«https://jsonplaceholder.typicode.com/users», { headers }, options) //A promiseFn with a fetch request and JSON deserialization will be created. //You can then call ‘run’ with an optional callback argument to change the ‘init’ parameter provided to ‘fetch’ at the last minute. function clickHandler1() { run(init => ({ …init, headers: { …init.headers, authentication: «…», }, })) } //Instead, you can use an object that will be shared across ‘init’. //Note that this is not a deep merge, thus properties from the original ‘init’ parameter may be overridden. function clickHandler2() { run({ body: JSON.stringify(formValues) }) } }

1234567891011121314151617181920212223242526 import { useFetch } from «react-async» const AppComponent = () => {  const headers = { Accept: «application/json» }  const { data, error, isPending, run } = useFetch(«https://jsonplaceholder.typicode.com/users», { headers }, options)  //A promiseFn with a fetch request and JSON deserialization will be created.//You can then call ‘run’ with an optional callback argument to change the ‘init’ parameter provided to ‘fetch’ at the last minute.    function clickHandler1() {    run(init => ({      …init,      headers: {        …init.headers,        authentication: «…»,      },    }))  } //Instead, you can use an object that will be shared across ‘init’.//Note that this is not a deep merge, thus properties from the original ‘init’ parameter may be overridden.    function clickHandler2() {    run({ body: JSON.stringify(formValues) })  }}

3. Функция createInstance()

React Async предлагает фабричную функцию createInstance(). Она позволяет создавать экземпляры компонентов с такими параметрами по умолчанию, как onResolve и onRejectcallbacks. В приведенном ниже примере показано, как мы можем создать собственный экземпляр Asynccomponent с помощью createInstance().

JavaScript import React from «react»; import ReactDOM from «react-dom»; import «./styles.css»; import { createInstance } from «react-async» const loadUsers = async ({ id }) => { const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`) if (!res.ok) throw new Error(res.statusText) return res.json() } const AsyncUser = createInstance({ promiseFn: loadUsers }, «AsyncUser») const App = () => ( <AsyncUser id={1}> <AsyncUser.Fulfilled>{user => `Hello ${user.name}`}</AsyncUser.Fulfilled> </AsyncUser> ) const rootElement = document.getElementById(«root»); ReactDOM.render(<App />, rootElement);

123456789101112131415161718192021 import React from «react»;import ReactDOM from «react-dom»;import «./styles.css»;import { createInstance } from «react-async» const loadUsers = async ({ id }) => {  const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)  if (!res.ok) throw new Error(res.statusText)  return res.json()} const AsyncUser = createInstance({ promiseFn: loadUsers }, «AsyncUser»)     const App = () => (      <AsyncUser id={1}>        <AsyncUser.Fulfilled>{user => `Hello ${user.name}`}</AsyncUser.Fulfilled>      </AsyncUser>    ) const rootElement = document.getElementById(«root»);ReactDOM.render(<App />, rootElement);

По умолчанию createInstance() принимает два входных параметра: defaultOptions и displayName.

Декларативная выборка данных с React Async

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

Функция loadUsers — defaultOption.

AsyncUser — отображаемое имя экземпляра.

Компоненты-помощники в React Async

Помимо компонента Async, React Async предоставляет несколько вспомогательных компонентов, чтобы сделать JSX более декларативным и понятным.

Эти вспомогательные компоненты могут принимать элемент React или функцию и включать или отключать рендеринг в зависимости от текущего состояния. Мы можем передать текущее состояние в useAsync или Async с помощью класса Context. Вот пример использования useAsync с хелперами. Это очень похоже на использование props.

JavaScript import { useAsync, IfPending, IfFulfilled, IfRejected } from «react-async» const loadUsers = async ({id}) => { // … } const MyComponent = () => { const state = useAsync({ promiseFn: loadUsers, id: 1 }) return ( <> <IfPending state={state}>Loading…</IfPending> <IfRejected state={state}>{error => `Something went wrong: ${error.message}`}</IfRejected> <IfFulfilled state={state}> {data => ( <div> <strong>User data:</strong> {JSON.stringify(data,2)} </div> )} </IfFulfilled> </> ) }

1234567891011121314151617181920212223 import { useAsync, IfPending, IfFulfilled, IfRejected } from «react-async» const loadUsers = async ({id}) => {  // …} const MyComponent = () => {  const state = useAsync({ promiseFn: loadUsers, id: 1 })  return (    <>      <IfPending state={state}>Loading…</IfPending>      <IfRejected state={state}>{error => `Something went wrong: ${error.message}`}</IfRejected>      <IfFulfilled state={state}>        {data => (          <div>            <strong>User data:</strong>            {JSON.stringify(data,2)}          </div>        )}      </IfFulfilled>    </>  )}

В приведенном выше примере я использовал три вспомогательных компонента:

IfPending — отображается только пока промис находится в ожидании (загрузка / отключение).

IfRejected — отображается только в том случае, если промис отклонен.

IfFulfilled — отображается только тогда, когда промис выполнен (преобразовано в значение, может быть неопределенным).

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

Дополнительные возможности React Async

В React Async есть специальный пакет DevTools, который упрощает отладку и разработку асинхронных состояний приложения. Вы можете установить его с помощью NPM или Yarn:

JavaScript //NPM npm install —save react-async-devtools //Yarn yarn add react-async-devtools

12345 //NPMnpm install —save react-async-devtools //Yarnyarn add react-async-devtools

После установки вам необходимо импортировать его и отобразить компонент DevTools в корне вашего приложения следующим образом:

JavaScript import DevTools from «react-async-devtools» export const Root = () => ( <> <DevTools /> <App /> </> )

12345678 import DevTools from «react-async-devtools» export const Root = () => (  <>    <DevTools />    <App />  </>)

Кроме того, React Async предлагает множество вариантов конфигурации для обработки особых сценариев. Эти конфигурации могут быть отправлены как props в <Async {… options}> или как объект для useAsync (options). Некоторые из наиболее часто используемых вариантов конфигурации:

promise — уже запущенный экземпляр Promise.

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

initialValue — предоставляет исходные данные или ошибки для рендеринга на стороне сервера.

onResolve — обратный вызов, при разрешении Promise.

onReject — обратный вызов, при отклонении Promise.

onCancel — обратный вызов, при отмене обещания.

Заключение

В этой статье я обсудил, как использовать библиотеку React Async для декларативной выборки данных. Она нацелена на выборку данных как можно ближе к тому месту, где они будут использоваться, просто используя декларативный синтаксис и собственные промисы.

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

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

Спасибо за внимание!!

Автор: Piumi Liyana Gunawardhana

Источник: webformyself.com

Оставьте ответ

Ваш электронный адрес не будет опубликован.