React Suspense

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

Альтернативный HTML может представлять собой компонент, текст или любой валидный контент.


Что такое Suspense?

Suspense — это специальная возможность React, предназначенная для демонстрации альтернативного контента (например, индикатора загрузки), пока данные или компоненты загружаются.

Самыми распространёнными случаями использования Suspense являются:

  • Загрузка данных с помощью специализированных библиотек, поддерживающих Suspense (например, Relay Modern).
  • Динамическая загрузка компонентов с помощью React.lazy().

Как использовать Suspense?

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

Пример

Допустим, компонент Fruits загружается медленно (примерно две секунды). Мы можем использовать компонент Suspense, чтобы показать индикатор загрузки, пока компонент загружается:


import { createRoot } from 'react-dom/client';
import { Suspense } from 'react';
import Fruits from './Fruits';

function App() {
  return (
    <div>
      <Suspense fallback={<div>Загрузка...</div>}>
        <Fruits />
      </Suspense>
    </div>
  );
}

createRoot(document.getElementById('root')).render(
  <App />
);


Использование Suspense с "ленивой" загрузкой компонентов

Ещё одно распространённое применение Suspense — это динамическая загрузка компонентов с помощью React.lazy(). Это позволяет импортировать компоненты "лениво", показывая альтернативный контент (например, индикатор загрузки), пока компонент загружается.

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

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

Давайте сначала создадим пример без использования ленивой загрузки, где мы не будем имитировать двухсекундную задержку:

Пример

В этом примере сообщение о загрузке появляется слишком быстро, и вы его фактически не заметите:


import { createRoot } from 'react-dom/client';
import { Suspense } from 'react';
import Cars from './Cars';

function App() {
  return (
    <div>
      <Suspense fallback={<div>Загрузка...</div>}>
        <Cars />
      </Suspense>
    </div>
  );
}

createRoot(document.getElementById('root')).render(
  <App />
);

Теперь попробуем применить ленивую загрузку с помощью React.lazy():

Пример

Тот же самый пример, что и выше, но с использованием ленивой загрузки:


import { createRoot } from 'react-dom/client';
import { Suspense, lazy } from 'react';

const Cars = lazy(() => import('./Cars')); // Ленивая загрузка компонента

function App() {
  return (
    <div>
      <Suspense fallback={<div>Загрузка...</div>}>
        <Cars />
      </Suspense>
    </div>
  );
}

createRoot(document.getElementById('root')).render(
  <App />
);

Объяснение примера:

  • lazy() позволяет загружать компонент динамически.
  • Suspense отображает альтернативный контент, пока компонент загружается.

Несколько компонентов с Suspense

Один компонент Suspense может содержать несколько лениво загружаемых компонентов:

Пример


import { createRoot } from 'react-dom/client';
import { Suspense, lazy } from 'react';

const Header = lazy(() => import('./Header'));
const Content = lazy(() => import('./Content'));
const Sidebar = lazy(() => import('./Sidebar'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Загрузка...</div>}>
        <Header />
        <div style={{ display: 'flex' }}>
          <Sidebar />
          <Content />
        </div>
      </Suspense>
    </div>
  );
}

createRoot(document.getElementById('root')).render(
  <App />
);


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