Skip to main content

Що нового про API use (читання ресурсів, Promise тощо)?

Що таке use()

use() - це новий React-API, який дозволяє напряму читати асинхронні ресурси (Promise) або контексти (Context) під час рендера, без хуків, без useEffect і без локальних станів.

Раніше React не дозволяв "чекати" проміси всередині компонента - потрібно було використовувати useEffect(), useState(), завантажувачі даних, suspense-обгортки тощо. Тепер React вміє "розуміти" проміси сам.


Синтаксис

javascript
const data = use(resource);
  • якщо resource - Promise, React призупиняє рендер (suspends), поки проміс не завершиться, і потім продовжує рендер з результатом;
  • якщо resource - контекст, use() просто повертає поточне значення (аналог useContext()).

Як це працює

React 19 впровадив підтримку асинхронного рендерингу на рівні ядра. Тепер, якщо компонент викликає use(promise):

  1. React "бачить", що це Promise;
  2. "Призупиняє" рендер компонента (suspend);
  3. Показує найближчий <Suspense fallback={...}>;
  4. Коли проміс виконується - React відновлює рендер з отриманими даними.

Це перетворює асинхронний код на чисту декларацію даних.


Приклад 1. Читання даних напряму з Promise

До React 19:

javascript
function UserProfile() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user').then(r => r.json()).then(setUser); }, []); if (!user) return <Spinner />; return <h1>{user.name}</h1>; }

Мінуси: стан, ефекти, зайві рендери, "мигання" при першому завантаженні.


Тепер з React 19 + use():

javascript
function fetchUser() { return fetch('/api/user').then(r => r.json()); } function UserProfile() { const user = use(fetchUser()); // React сам дочекається відповіді return <h1>{user.name}</h1>; }

Уся асинхронна поведінка обробляється всередині React - жодних useEffect і useState, все синхронно і декларативно. Якщо дані ще не готові, React покаже Suspense fallback.


Приклад 2. Спільна робота з <Suspense>

javascript
function App() { return ( <Suspense fallback={<Spinner />}> <UserProfile /> </Suspense> ); }

React "заморожує" дерево, поки use(fetchUser()) не поверне результат, і показує <Spinner /> під час очікування.


Приклад 3. Використання use() з контекстом

javascript
const ThemeContext = createContext('light'); function Toolbar() { const theme = use(ThemeContext); // замість useContext(ThemeContext) return <div className={theme}>Toolbar</div>; }

use(context) = сучасний короткий варіант useContext(context) (працює і для Server Components, і для Client Components).


Приклад 4. Робота з асинхронними функціями і Suspense

javascript
async function getPost(id) { const res = await fetch(`/api/posts/${id}`); return res.json(); } function Post({ id }) { const post = use(getPost(id)); // React сам призупинить рендер return <article> <h1>{post.title}</h1> <p>{post.body}</p> </article>; }

Якщо getPost() поверне Promise, React сам:

  • призупинить компонент;
  • покаже fallback;
  • продовжить, коли post буде готовий.

Приклад 5. Комбінація з серверними Actions (React Server Components)

У React 19 серверні компоненти тепер теж можуть використовувати use() для очікування даних:

javascript
// Server Component import { getUserData } from '@/lib/data'; export default function Page() { const user = use(getUserData()); return <Profile user={user} />; }

На сервері React дочекається getUserData(), згенерує HTML і відправить клієнту вже готову розмітку без "мигання".


Як use() пов'язаний із Suspense і Concurrent Rendering

МеханізмРоль
SuspenseПоказує "fallback", поки дані не готові
Concurrent RenderingДозволяє React призупиняти і відновлювати рендеринг
use()Ініціює очікування даних під час рендера

Разом ці три технології дають "асинхронний React": дані, компоненти і переходи тепер можна чекати прямо в JSX, без імперативного коду.


Приклад 6. Комбінація з Actions

javascript
async function createPostAction(formData) { await api.createPost(formData); return getAllPosts(); // повертає Promise } function Posts() { const posts = use(getAllPosts()); return ( <form action={createPostAction}> <ul> {posts.map(p => <li key={p.id}>{p.title}</li>)} </ul> <input name="title" /> <button>Add</button> </form> ); }

Після виконання Action React автоматично викличе use() повторно, щоб перечитати дані (аналог "рефетча").


Коли use() корисний

Ідеальні сценарії:

  • Асинхронні завантаження даних у Server Components;
  • SSR + Streaming Suspense - читання API без useEffect;
  • Форми і Actions, де результат одразу використовується в UI;
  • Інтеграція з Suspense і React Cache (наприклад, патерн cache(fetch)).

Коли НЕ варто використовувати

  • У старих проєктах без Concurrent Rendering (React <18);
  • У компонентах, де тобі потрібно вручну контролювати завантаження (наприклад, polling, websockets);
  • У "чисто клієнтських" частинах UI, де Suspense не використовується.

Важливо пам'ятати

  • use() можна викликати тільки під час рендера, як звичайний хук;
  • React сам визначає, що це Promise, і робить "suspend";
  • Працює тільки при увімкненому Concurrent Rendering (React 18+);
  • Не замінює useState чи useEffect - це інша парадигма: декларативне очікування даних;
  • У React 19 use() стабілізований, але в React 18 він був експериментальним.

Підсумок

use() - це новий API React 19 для читання промісів, ресурсів і контекстів прямо під час рендера. Він робить роботу з асинхронними даними чистою, синхронною на вигляд і повністю інтегрованою з Suspense. Це основа нової моделі асинхронного React - разом із Suspense, Actions, Server Components і useOptimistic().


Коротко:

МожливістьОпис
use(promise)React "чекає" результат Promise, призупиняє рендер
use(context)Аналог useContext(context)
Suspense-інтеграціяReact показує fallback, поки дані не готові
Працює з Server ComponentsТак
Працює з ActionsТак
Імперативний код (useEffect) не потрібенТак
Статус у React 19Стабільний

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

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

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