Skip to main content

Що робить Suspense у React 18?

Що таке Suspense

<Suspense> - це компонент-обгортка, який дозволяє призупиняти рендеринг частини інтерфейсу, поки не будуть готові якісь дані (або компоненти), і показувати запасний UI (fallback) замість "завислої" ділянки.

Простіше кажучи:

Suspense = «Покажи скелет/спінер, поки React чекає дані або модуль».


Основна ідея

До React 18 Suspense працював тільки для лінивого завантаження компонентів (через React.lazy). У React 18 він став універсальним інструментом очікування: тепер він вміє працювати з асинхронними даними, серверним рендерингом і стрімінгом.


Приклад базового використання

javascript
import React, { Suspense, lazy } from 'react'; const Profile = lazy(() => import('./Profile')); function App() { return ( <Suspense fallback={<div>Loading profile...</div>}> <Profile /> </Suspense> ); }

Поки компонент Profile завантажується, React призупиняє його рендер і показує <div>Loading profile...</div>. Коли модуль підвантажиться - React "відновить" рендер і вставить готовий компонент.


Що нового з'явилося в React 18

1. Suspense тепер працює на сервері (SSR)

React 18 додав стрімінговий серверний рендеринг:

  • тепер сервер може віддавати HTML частинами,
  • і Suspense дозволяє рендерити "готові шматки" одразу, не чекаючи, поки весь застосунок буде повністю зібраний.

Приклад:

javascript
<Suspense fallback={<Skeleton />}> <Comments /> </Suspense>

Якщо <Comments> завантажується довше - React на сервері:

  1. віддає HTML без цього блоку;
  2. показує Skeleton;
  3. пізніше "дострімить" готовий HTML блоку <Comments>;
  4. на клієнті відбудеться гідратація без ривків.

Нові API для цього:

javascript
renderToPipeableStream() // для Node.js renderToReadableStream() // для Deno, Edge та ін.

2. Suspense тепер розуміє асинхронні дані (через бібліотеки)

React 18 сам по собі ще не вміє "fetch-ити" дані, але Suspense тепер може чекати Promise, якщо його кидає компонент або хук. Це використовується у фреймворках (Next.js 13+, Remix, RSC).

Наприклад, у Next.js:

javascript
export default async function Page() { const user = await getUser(); // async-компонент return ( <Suspense fallback={<Spinner />}> <UserInfo user={user} /> </Suspense> ); }

React автоматично призупинить рендер, поки getUser() не завершиться, а в цей час покаже Spinner.


3. Сумісність з Concurrent Rendering

Suspense заснований на конкурентному рендерингу React 18. Це означає, що React може:

  • призупиняти рендер компонента,
  • продовжувати рендер інших частин UI,
  • відновлювати рендер пізніше - без блокування інтерфейсу.

Тобто React буквально "рендерить наперед", але не показує компонент, поки він не готовий.


4. Новий рівень UX

Suspense вирішує проблему "смикання інтерфейсу":

  • немає різкого зникнення контенту під час завантаження;
  • можна показувати placeholder / skeleton плавно;
  • можна комбінувати Suspense для різних частин сторінки (nested Suspense).

Приклад:

javascript
<Suspense fallback={<MainSkeleton />}> <MainContent /> <Suspense fallback={<SidebarSkeleton />}> <Sidebar /> </Suspense> </Suspense>

5. Як React "зупиняє" рендер

Механіка проста:

  1. Всередині компонента виникає Promise (наприклад, при лінивому імпорті або завантаженні даних);
  2. React "зустрічає" цей Promise;
  3. Він зупиняє рендер цієї частини дерева;
  4. Показує fallback;
  5. Коли Promise виконано -> React відновлює рендер з реальними даними.

6. Що Suspense не робить сам по собі

  • Не виконує запити (fetch, axios) напряму - він лише керує очікуванням.
  • Не керує помилками (catch) - для цього потрібен <ErrorBoundary>.
  • Не замінює useEffect - Suspense використовується під час рендера, а не після.

Підсумок

<Suspense> - це декларативний механізм очікування: React призупиняє рендер частини дерева, показує fallback, а потім автоматично відновлює рендер, коли дані або модулі готові.


Коротко:

МожливістьReact 17React 18
Lazy loading компонентівТакТак
Очікування даних (Promise)НіТак
SSR + StreamingНіТак
Кілька рівнів SuspenseОбмеженоСтабільно
Підтримка Concurrent RenderingНіТак

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.