Skip to main content

Що таке "Transition Updates"?

Що таке Transition Updates

Transition Update - це низькопріоритетне оновлення стану, яке React може виконати пізніше, призупинити чи скасувати, якщо саме зараз відбуваються важливіші (термінові) дії користувача.

Простіше кажучи:

Transitions = оновлення, які можна відкласти, щоб не заважати швидкому відгуку UI.


1. Проблема, яку вирішують Transitions

До React 18 усі виклики setState() були рівнозначні: React виконував усі оновлення з однаковим пріоритетом.

Приклад:

Користувач друкує текст, і при кожному введенні фільтрується величезний список:

javascript
function Search() { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); function handleChange(e) { const value = e.target.value; setQuery(value); setResults(filterBigList(value)); // важке оновлення } return ( <> <input value={query} onChange={handleChange} /> <ResultsList items={results} /> </> ); }

У React 17 UI може "лагати": поле вводу підвисає, поки React рендерить список.


2. Як вирішує це React 18 з Transition Updates

Тепер можна позначити частину оновлень як нетермінові (transitions):

javascript
import { useTransition } from 'react'; function Search() { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); const [isPending, startTransition] = useTransition(); function handleChange(e) { const value = e.target.value; setQuery(value); // термінове оновлення (ввід) startTransition(() => { setResults(filterBigList(value)); // відкладене (важке) оновлення }); } return ( <> <input value={query} onChange={handleChange} /> {isPending && <Spinner />} {/* поки чекаємо */} <ResultsList items={results} /> </> ); }

Тепер:

  • поле вводу оновлюється миттєво;
  • React відкладає фільтрацію списку;
  • можна показати індикатор завантаження isPending, поки Transition не завершений.

3. Що робить startTransition() під капотом

  1. React отримує функцію, передану в startTransition();
  2. позначає оновлення всередині як низькопріоритетні;
  3. якщо в цей час приходять термінові оновлення (наприклад, натискання клавіш) - React призупиняє Transition, щоб інтерфейс не "завис";
  4. щойно потік звільняється - React відновлює виконання Transition.

4. "Термінові" vs "Перехідні" оновлення

Тип оновленняПрикладПріоритетМожна перервати?Приклад API
Urgent (термінові)Набір тексту, кліки, фокус, навігаціяВисокийНіsetState() напряму
Transition (відкладені)Фільтрація, сортування, підвантаження данихНизькийТакstartTransition() / useTransition()

React тепер розуміє різницю між UX-важливим і ресурсно-важким оновленням.


5. Як React вирішує, що рендерити першим

  • React працює з двома чергами оновлень:
    • терміновими (input, focus, scroll тощо);
    • відкладеними (transitions).
  • Якщо користувач вводить текст - термінові оновлення проходять негайно.
  • Усі transitions React може:
    • відкласти до наступного кадру;
    • призупинити, якщо користувач продовжує ввід;
    • скасувати, якщо прийшли нові дані;
    • виконати заново, коли користувач зупинився.

6. Приклад з індикатором isPending

useTransition() повертає:

  • isPending - прапорець, що вказує, що Transition зараз виконується;
  • startTransition(callback) - функцію для запуску низькопріоритетних оновлень.
javascript
const [isPending, startTransition] = useTransition(); startTransition(() => { setSearchResults(fetchFilteredResults(query)); });

Коли React призупиняє рендер, isPending = true - можна показати спінер, скелетон чи напис "Завантаження…".


7. React сам керує Transitions

Transitions працюють лише при активному Concurrent Rendering, тобто коли корінь застосунку створений через:

javascript
import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')); root.render(<App />);

Якщо ти використовуєш старий ReactDOM.render(), startTransition просто не дасть ефекту - React не зможе призупиняти рендер.


8. Приклад з асинхронними діями

javascript
function Products() { const [filter, setFilter] = useState('all'); const [data, setData] = useState([]); const [isPending, startTransition] = useTransition(); const handleFilter = (newFilter) => { startTransition(async () => { const res = await fetch(`/api/products?filter=${newFilter}`); const data = await res.json(); setData(data); setFilter(newFilter); }); }; return ( <> <Filters onChange={handleFilter} /> {isPending && <Skeleton />} <ProductList items={data} /> </> ); }

UI залишається відповідним, навіть якщо запит до API займає час.


9. Нове в React 19

React 19 покращив Transitions - тепер startTransition() може бути асинхронним:

javascript
await startTransition(async () => { await someAsyncOperation(); });

Більше не потрібно вручну керувати станом очікування - React сам розуміє, коли Transition завершений.


Підсумок

Transition Updates - це оновлення стану, які React виконує плавно, асинхронно і без лагів інтерфейсу, відкладаючи їх, поки користувач взаємодіє з UI.


Коротке порівняння

ХарактеристикаЗвичайний setStateTransition Update
ПріоритетВисокийНизький
Можна перерватиНіТак
Затримка в UIМожлива (лаг)Немає
Основне застосуванняПодії UI (ввід, клік)Довгі обчислення, фільтри, завантаження
APIsetState()useTransition() / startTransition()

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

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

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