Що нового про API use (читання ресурсів, Promise тощо)?
Що таке use()
use()- це новий React-API, який дозволяє напряму читати асинхронні ресурси (Promise) або контексти (Context) під час рендера, без хуків, без useEffect і без локальних станів.
Раніше React не дозволяв "чекати" проміси всередині компонента -
потрібно було використовувати useEffect(), useState(), завантажувачі даних, suspense-обгортки тощо.
Тепер React вміє "розуміти" проміси сам.
Синтаксис
const data = use(resource);- якщо
resource- Promise, React призупиняє рендер (suspends), поки проміс не завершиться, і потім продовжує рендер з результатом; - якщо
resource- контекст,use()просто повертає поточне значення (аналогuseContext()).
Як це працює
React 19 впровадив підтримку асинхронного рендерингу на рівні ядра.
Тепер, якщо компонент викликає use(promise):
- React "бачить", що це Promise;
- "Призупиняє" рендер компонента (suspend);
- Показує найближчий
<Suspense fallback={...}>; - Коли проміс виконується - React відновлює рендер з отриманими даними.
Це перетворює асинхронний код на чисту декларацію даних.
Приклад 1. Читання даних напряму з Promise
До React 19:
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():
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>
function App() {
return (
<Suspense fallback={<Spinner />}>
<UserProfile />
</Suspense>
);
}React "заморожує" дерево, поки use(fetchUser()) не поверне результат,
і показує <Spinner /> під час очікування.
Приклад 3. Використання use() з контекстом
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
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() для очікування даних:
// 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
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 | Стабільний |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.