Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить useTransition()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`useTransition()` дозволяє **позначити оновлення стану як "перехідне"** (не термінове), щоб React **не блокував інтерфейс** під час важких ререндерів. **Ключове:** useTransition каже React: "це оновлення можна зробити пізніше, не гальмуй UI".Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `useTransition()` `useTransition()` дозволяє **позначити оновлення стану як "перехідне"** (не термінове), щоб React **не блокував інтерфейс** під час важких ререндерів. > Простіше кажучи: > `useTransition()` каже React: > **"Це оновлення можна зробити пізніше, не гальмуй UI."** --- ## Синтаксис ```javascript const [isPending, startTransition] = useTransition(); ``` - `startTransition(callback)` - обгортає код, який запускає *неспішне* оновлення. - `isPending` - булеве значення (`true` під час переходу), показує, що React усе ще "рендерить" відкладений стан. --- ## Приклад Уяви, що в тебе є велика кількість даних, і користувач вводить текст для фільтрації списку. ### Без `useTransition` ```javascript 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` ```javascript 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 може відкласти | --- ## Приклад: перемикання сторінок ```javascript 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-запитів |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.