Высокоуровневый обзор Concurrent React

Нажмите здесь, чтобы прочитать статью на японском языке:
https://zenn.dev/takuyakikuchi/articles/91ccf7037d6375

Об этой статье

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

цитата из React v18.0 — Блог React

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

Concurrent React — это не функция, а новый механизм

Concurrency — это не функция, как таковая. Это новый закулисный механизм, который позволяет React одновременно готовить несколько версий пользовательского интерфейса.

цитата из React v18.0 — React Blog

Прежде всего, это не функция, как было сказано выше, Concurrent React — это новый механизм (новая модель рендеринга ядра React), позволяющий React иметь несколько версий пользовательского интерфейса, готовых одновременно.

Новое заключается в следующем

  • До: рендеринг является коллективным, непрерывным и синхронным.
  • Concurrent: рендеринг прерывистый и асинхронный (ключевая характеристика Concurrent React).

С этим новым механизмом

Пользователи получат более плавный пользовательский опыт,

А разработчики смогут более декларативно описывать управление пользовательским интерфейсом на основе состояния загрузки компонентов.

Чтобы более конкретно понять, что это значит, давайте поговорим об одной из особенностей Concurrent React — Suspense.

Suspense

Вот концептуальное объяснение Suspense с простым примером кода.

(Код взят из React Top-Level API — React)

<Suspense fallback={<Spinner />}>
  <Comments />
</Suspense>
Вход в полноэкранный режим Выход из полноэкранного режима

Suspense обрабатывает ситуацию, когда внутренний компонент загружается, но еще не готов к рендерингу.

В предыдущем разделе я сказал, что рендеринг прерывается и является асинхронным, что является важной характеристикой Concurrent React.

В этом примере,

  1. рендеринг <Comments> приостановлен на время загрузки (прерывистый)
  2. когда <Commnets> завершает загрузку, он отображается (асинхронный рендеринг).

Таким образом, пользовательский интерфейс отображается последовательно, что делает UX плавным.

Вот еще один пример.

function ProfilePage() {
  return (
    <PageLayout>
      <Suspense fallback={<MyProfileSkeleton />}>
        <MyProfile />
      </Suspense>
      <Suspense fallback={<AchievementsSkeleton />}>
        <Achievements />
      </Suspense>
      <Suspense fallback={<OrganizationSkeleton />}>
        <Organizations />
      </Suspense>
      <Suspense fallback={<ContributionsSkeleton />}>
        <Contributions />
      </Suspense>
    </PageLayout>
  );
};
Вход в полноэкранный режим Выход из полноэкранного режима

В этом примере каждый из них заключен в <Suspense>.

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

Примеры использования Suspense

Теперь давайте рассмотрим конкретный пример использования Suspense.

Ленивая загрузка компонентов с помощью React.lazy.

Единственный вариант использования на данный момент. (См.: React Top-Level API — React)

// This component is loaded dynamically
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    // Displays <Spinner> until OtherComponent loads
    <React.Suspense fallback={<Spinner />}>
      <div>
        <OtherComponent />
      </div>
    </React.Suspense>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Это поддерживается с версии React v.16.6, так что вы, возможно, уже знакомы с этим сценарием использования.

В примере выше отображается содержимое <Spinner> для отката в ожидании загрузки ленивого компонента <OtherComponent> с помощью React.lazy.

React.lazy — это функция, используемая для выполнения разделения кода, а рендеринг ленивого компонента внутри компонента Suspense обеспечивает последовательное отображение пользовательского интерфейса.
Расщепление кода — React

Приостановка с получением данных

На данный момент единственным официально поддерживаемым вариантом использования является использование React.lazy, но видение команды React для Suspense кажется гораздо более масштабным.

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

Цитата из React v18.0 — React Blog

Одним из таких способов является использование Suspense для получения данных.

Обычный способ

[※Alert: Ниже приведен пример кода с использованием нотации Apollo Client, но Apollo Client в настоящее время не поддерживает Suspense.

Вопрос на Github о поддержке Suspense: https://github.com/apollographql/apollo-client/issues/9627].

// Dog.jsx
function Dogs() {
  const { loading, error, data } = useQuery(GET_DOGS);

  if (loading) return 'Loading...';
  if (error) return `Error! ${error.message}`;

  return (
    <ul>
      {data.dogs.map((dog) => (
        <li key={dog.id}>{dog.breed}</li>
      ))}
    </ul>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

В компонентах, выполняющих асинхронную загрузку, «процесс во время загрузки» и «процесс после завершения загрузки» объединены.

Подвесной способ

// Dogs.jsx
function Dogs() {
  const { data } = useQuery(GET_DOGS);

  return (
    <ul>
      {data.dogs.map((dog) => (
        <li key={dog.id}>{dog.breed}</li>
      ))}
    </ul>
  );
};
Вход в полноэкранный режим Выход из полноэкранного режима
// App.jsx
function App() {
  return (
    <React.Suspense fallback={<Spinner />}>
      <Dogs />
    </React.Suspense>
  );
};
Вход в полноэкранный режим Выход из полноэкранного режима

Если предыдущая программа была процедурной, например if (isLoading), то обработка состояния загрузки стала более декларативной. Это упрощает обязанности компонента, отвечающего за загрузку данных.

Вышеизложенное — это просто идея в качестве примера кода, но если вы хотите начать использовать ее на практике, вы можете начать использовать Suspense для получения данных в React 18 с помощью таких фреймворков, как Relay, Next.js, Hydrogen и Remix. (* Пока не рекомендуется в качестве общей стратегии в том смысле, что это технически возможно).

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

См. раздел Suspense во фреймворке данных

Другие примеры использования

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

Компоненты на стороне сервера + Suspense — это функция, которая лично мне очень нравится.

  • Возможность рендеринга на стороне сервера в потоковом режимеhttps://reactjs.org/docs/react-api.html#reactsuspense-in-server-side-rendering
  • Приостановка во время гидратацииhttps://reactjs.org/docs/react-api.html#reactsuspense-during-hydration

Резюме

Concurrent React — это не только лучший пользовательский опыт, но, как разработчик, я чувствую, что мы должны проектировать для функций, которые будут доступны с Concurrent React.

Я уверен, что как новые возможности Concurrent React, так и поддержка Concurrent в экосистеме React будут все больше и больше обновляться в будущем, поэтому следите за Concurrent React в будущем.

Ссылка

  • React 18に備えるにはどうすればいいの? 5分で理解する — Qiita
  • React v18.0 — React Blog

Оцените статью
devanswers.ru
Добавить комментарий