Що робить startTransition()?
Що робить startTransition()
startTransition() каже React:
"Це оновлення не термінове. Можна почекати, поки користувач закінчить взаємодію, і виконати його пізніше, щоб не гальмувати інтерфейс."
Синтаксис
import { startTransition } from 'react';
startTransition(() => {
setState(newValue);
});React виконає це оновлення з низьким пріоритетом. Якщо в цей час відбувається щось важливе (наприклад, користувач друкує або клікає) - React спочатку оновить термінові речі, а потім "доробить" transition.
Навіщо це потрібно
Без startTransition усі оновлення вважаються терміновими.
Це означає, що React одразу перериває все, щоб відрендерити новий UI.
Наприклад, користувач друкує в пошуковому рядку, а ти фільтруєш величезний список.
function Search() {
const [query, setQuery] = useState('');
const [filtered, setFiltered] = useState(data);
const handleChange = e => {
const value = e.target.value;
setQuery(value);
setFiltered(filterItems(data, value)); // важка операція
};
return (
<>
<input value={query} onChange={handleChange} />
<List items={filtered} />
</>
);
}При кожному введенні символу React:
- оновлює
query, - фільтрує весь список,
- перерендерює купу елементів.
Інтерфейс починає "лагати".
З startTransition - плавна магія
import { startTransition } from 'react';
function Search() {
const [query, setQuery] = useState('');
const [filtered, setFiltered] = useState(data);
const handleChange = e => {
const value = e.target.value;
setQuery(value); // термінове оновлення - текст в input змінюється миттєво
startTransition(() => {
setFiltered(filterItems(data, value)); // низькопріоритетне оновлення
});
};
return (
<>
<input value={query} onChange={handleChange} />
<List items={filtered} />
</>
);
}Тепер React розділяє оновлення:
setQuery-> високий пріоритет (UI має відповісти миттєво);setFiltered-> низький пріоритет (можна почекати).
Результат:
- поле вводу працює без лагів;
- список фільтрується трохи пізніше, коли React звільниться.
Що робить React всередині
- React ставить transition-задачу в чергу з низьким пріоритетом;
- Продовжує обробляти всі термінові оновлення (ввід, кліки, hover тощо);
- Коли є "вікно часу" - рендерить низькопріоритетне оновлення;
- Якщо користувач знову вводить символ - React може перервати старий рендер і почати новий.
Це і є "паралельний рендеринг" (concurrent rendering).
Приклад з підсвіткою "в процесі переходу"
React надає хук useTransition(), щоб відстежувати,
чи триває зараз перехід (transition).
import { useState, useTransition } from 'react';
function Search() {
const [query, setQuery] = useState('');
const [filtered, setFiltered] = useState(data);
const [isPending, startTransition] = useTransition();
const handleChange = e => {
const value = e.target.value;
setQuery(value);
startTransition(() => {
setFiltered(filterItems(data, value));
});
};
return (
<>
<input value={query} onChange={handleChange} />
{isPending && <p>Оновлюємо список...</p>}
<List items={filtered} />
</>
);
}Тепер isPending = true, поки React виконує перехід.
Можна показувати спіннер, індикатор завантаження тощо.
Ключова ідея
React 18 вміє пріоритизувати оновлення:
| Пріоритет | Приклад | Як виконується |
|---|---|---|
| Термінові | Ввід, кліки, анімації | Негайно |
| Нетермінові (Transition) | Фільтрація, рендер списків, завантаження | Коли є час |
Коли використовувати startTransition
Підходить для:
- фільтрації або сортування великих списків;
- перемикання вкладок, які завантажують дані;
- оновлення UI при зміні фільтрів, мови, теми, категорії;
- будь-яких операцій, де швидкість реакції важливіша за миттєвий рендер.
Не потрібен для:
- простих
setState; - миттєвих ефектів (модалки, кліки);
- випадків, де немає важкого рендера.
Чому це важливо
| Перевага | Що дає |
|---|---|
| UI залишається чутливим | Користувач може клікати і друкувати під час переходу |
| Розділення пріоритетів | React сам вирішує, що важливіше |
| Переривані рендери | React може скасувати старий перехід |
| Зниження лагів | Важкі оновлення не блокують інтерфейс |
Підсумок
| Що робить | Як працює |
|---|---|
startTransition() | Позначає оновлення як "нетермінове" |
| React 18 concurrent mode | Дозволяє переривати і пріоритизувати рендери |
| Високий пріоритет | Для миттєвого UI (input, кліки) |
| Низький пріоритет (transition) | Для важких операцій |
useTransition() | Хук для відображення "в процесі переходу" |
Простими словами:
startTransition()каже React: "Це не критично - зроби, коли буде час, але не блокуй інтерфейс користувача."
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.