Информативное руководство по использованию Suspense в React 18

Компонент React Suspense впервые был запущен в React 16.6, а затем был расширен с выпуском React 18. Первоначально React Suspense можно было использовать только для разделения кода с помощью React.lazy API. Тем не менее, команда React работала над улучшением возможностей Suspense с целью заставить его работать с выборкой данных и в будущем.

Это показывает, почему разработчикам React важно понимать, как работать с React Suspense. В этой статье обсуждается, как улучшить качество кода веб-загрузчиков с помощью Suspense в React 18.

Давайте начнем.

Понимание приостановки реакции

Начнем с того, как компонент <Suspense> работает с компонентами отложенной загрузки.

При использовании компонента «Приостановка» необходимо предоставить резервный вариант. Он принимает любые компоненты React или даже строку для рендеринга, пока загружается ленивый компонент.

Взгляните на приведенный ниже пример, в котором оболочка Suspense используется для отображения типичного загрузчика до тех пор, пока <LazyLoadComponent> не будет готов.

import { lazy, Suspense } from 'react';
const LazyLoadComponent = lazy(() => import('./LazyLoadComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<Loader />}>
      <div>
        <LazyLoadComponent />
      </div>
    </Suspense>
  );
}

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

Чтобы узнать, как это использовать, посмотрите фрагмент кода ниже.

<Suspense fallback={<MainLoader />}>
  <Suspense fallback={<SideContentLoader />}>
    <SideContent />
  </Suspense>
  <MainContent />
  <Suspense fallback={<CommentsLoader />}>
    <Comments />
  </Suspense>
</Suspense>

Обертки приостановки используются отдельно для компонентов <SideContent/> и <Comments/> в примере. В результате, если компонент <MainContent/> готов к загрузке, он сделает это независимо от того, загружены ли два других компонента. Однако, поскольку все три компонента являются дочерними элементами Suspense компонента <MainContent/>, два других компонента будут ожидать загрузки компонента <MainContent/>.

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

Теперь давайте посмотрим на улучшения, которые Suspense получил в React 18.

Улучшения приостановки в React 18

Рендеринг на стороне сервера

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

В обоих предыдущих примерах вы можете заменить ленивые компоненты обычными компонентами, и Suspense по-прежнему будет работать по тем же принципам.

Это значительно упрощает процесс добавления загрузчиков в ваше веб-приложение.

API-интерфейс startTransition

Еще одна новая функция React 18 — API startTransition, и ее можно использовать для улучшения использования Suspense.

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

Рассмотрим следующий пример кода, в котором два компонента вкладок, Cricket и Football, заключены в компонент Suspense.

const [isPending, startTransition] = useTransition();
function handleClick() {
  startTransition(() => {
    setTab('football');
  });
}
<Suspense fallback={<Loader/>}>
  <div style={{opacity: isPending ? 0.8 : 1 }}>
    {tab === 'cricket' ? <Cricket /> : <Football />}
  </div>
</Suspense>

Здесь, если useTransition() не использовалось, то загрузчик будет появляться каждый раз, когда пользователь переключается между вкладками. Однако при использовании, как показано, вкладка «Крикет» будет отображаться до тех пор, пока не будет готова вкладка «Футбол». Во время перехода пользователь сможет взаимодействовать с контентом как обычно. Значение isPending используется для определения того, происходит ли переход в данный момент или нет, и используется в примере для изменения непрозрачности компонента во время перехода.

Зачем использовать React Suspense

Без Suspense нам нужно получить доступ к состоянию и написать еще кучу кода для отображения загрузчиков в React. Фрагмент кода ниже демонстрирует, как отображать загрузчики без использования Suspense.

function MyComponent() {
  const [isLoading, setIsLoading] = useState(false);
  return (
      <div>
          {isLoading ? (
              <Loader />
          ) : (
              <AppContent />
          )}
      </div>
  );
}

На первый взгляд изменение с isLoading ? на <Suspense> может показаться незначительным, но в больших проектах оно будет иметь большое значение. Когда React улучшит Suspense для работы с выборкой данных, все станет еще лучше.

Suspense был добавлен в React 18 для получения данных в фреймворках Relay, Next.js, Hydrogen и Remix. Несмотря на то, что Suspense позволяет извлекать данные ad hoc, команда React пока не рекомендует его в качестве общей практики.

Заключение

В этой статье рассказывается о компоненте приостановки, новых улучшениях приостановки в React 18 и о том, почему вам следует использовать приостановку. Я надеюсь, что теперь у вас есть четкое представление о компоненте Suspense. Итак, начните использовать Suspense и улучшите качество своего кода React.

Спасибо за чтение и удачного кодирования!