Що робить useTransition()?
Що робить useTransition()
useTransition() дозволяє позначити оновлення стану як "перехідне" (не термінове),
щоб React не блокував інтерфейс під час важких ререндерів.
Простіше кажучи:
useTransition()каже React: "Це оновлення можна зробити пізніше, не гальмуй UI."
Синтаксис
const [isPending, startTransition] = useTransition();startTransition(callback)- обгортає код, який запускає неспішне оновлення.isPending- булеве значення (trueпід час переходу), показує, що React усе ще "рендерить" відкладений стан.
Приклад
Уяви, що в тебе є велика кількість даних, і користувач вводить текст для фільтрації списку.
Без useTransition
function Search() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const handleChange = (e) => {
const value = e.target.value;
setQuery(value);
// важка операція
setResults(filterBigData(value));
};
return (
<>
<input value={query} onChange={handleChange} />
<List data={results} />
</>
);
}Проблема:
- Кожне введення символу (
setQuery) одразу викликає важкийfilterBigData. - UI "фризиться" (гальмує) при кожному натисканні.
З useTransition
import { useState, useTransition } from "react";
function Search() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
const value = e.target.value;
setQuery(value);
startTransition(() => {
// це оновлення не термінове
setResults(filterBigData(value));
});
};
return (
<>
<input value={query} onChange={handleChange} />
{isPending && <p>Завантаження...</p>}
<List data={results} />
</>
);
}Тепер:
- React спочатку миттєво оновлює
query(термінове оновлення), - а потім, коли є час, робить
setResults(неспішне), - при цьому інтерфейс лишається відгукливим (можна продовжувати вводити текст).
Що робить React всередині
React 18 має Concurrent Renderer, який вміє призупиняти і переривати рендер, якщо є щось важливіше, наприклад, користувач набирає текст.
useTransition просто позначає частину роботи як:
"Не критично, якщо це почекає."
React тоді:
- призупиняє важкий рендер,
- показує старий UI,
- продовжує після звільнення головного потоку (main thread).
Значення, які повертаються
| Змінна | Тип | Опис |
|---|---|---|
isPending | boolean | true, поки перехід не завершений |
startTransition(callback) | function | обгортає "неспішні" оновлення |
Коли використовувати useTransition()
| Коли | Чому |
|---|---|
| Фільтрація, пошук, сортування у великих списках | Щоб не фризився ввід |
| Пагінація або навігація між великими компонентами | Щоб перехід не заморожував UI |
| Динамічне довантаження даних | Щоб не блокувати дії користувача |
| Коли потрібно візуально розділити "миттєві" і "відкладені" оновлення | Наприклад, isPending = true → показувати "Loading…" |
Коли не варто використовувати
| Ситуація | Чому |
|---|---|
Прості оновлення (setState у кнопці) | useTransition ускладнить код без користі |
| API-запити або асинхронні дані | Використовуй useEffect або useQuery |
| У тебе немає проблем із "лагами" UI | React сам достатньо оптимізує прості випадки |
Порівняння зі звичайним setState
| Оновлення | Що робить React |
|---|---|
setState() | Виконується одразу (високий пріоритет) |
startTransition(() => setState()) | Позначається як "низькопріоритетне", React може відкласти |
Приклад: перемикання сторінок
function Tabs({ tabs }) {
const [active, setActive] = useState(0);
const [isPending, startTransition] = useTransition();
return (
<>
{tabs.map((tab, i) => (
<button
key={i}
onClick={() => startTransition(() => setActive(i))}
disabled={isPending}
>
{tab.title}
</button>
))}
<div>
{isPending ? <p>Завантаження вкладки...</p> : tabs[active].content}
</div>
</>
);
}Перемикання миттєве, навіть якщо контент вкладки великий - React "довантажує" його спокійно, не блокуючи інтерфейс.
Підсумок
| Питання | Відповідь |
|---|---|
Що робить useTransition() | Дозволяє виконувати оновлення стану з низьким пріоритетом (відкладені) |
| Коли React виконує їх | Після термінових (введення тексту, кліки, hover тощо) |
| Що повертає | [isPending, startTransition] |
| Коли використовувати | Для важких обчислень, фільтрації, переходів між великими компонентами |
| Коли не варто | Для простих оновлень або асинхронних API-запитів |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.