Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить Suspense у React 18?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`<Suspense>`** - це компонент-обгортка, який дозволяє призупиняти рендеринг частини інтерфейсу, поки не будуть готові якісь дані (або компоненти), і показувати запасний UI (fallback) замість "завислої" ділянки. **Ключове:** у React 18 Suspense став універсальним інструментом очікування - він працює не тільки з `React.lazy`, а й з асинхронними даними, серверним стрімінгом і конкурентним рендерингом.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке `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 17 | React 18 | |---|---|---| | Lazy loading компонентів | Так | Так | | Очікування даних (Promise) | Ні | Так | | SSR + Streaming | Ні | Так | | Кілька рівнів Suspense | Обмежено | Стабільно | | Підтримка Concurrent Rendering | Ні | Так |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.