Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить startTransition()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`startTransition()`** повідомляє React, що оновлення всередині неї не термінові, і їх можна відкласти, призупинити або скасувати, щоб інтерфейс залишався миттєво відзивчивим для користувача. **Ключове:** зроби важливі речі (ввід, кліки) зараз, а важкі - потім, коли буде час.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротко: що робить `startTransition()` > `startTransition()` повідомляє React, що **оновлення всередині неї не термінові**, > і їх можна **відкласти, призупинити або скасувати**, > щоб інтерфейс залишався **миттєво відзивчивим** для користувача. Простіше кажучи: > "Зроби важливі речі (ввід, кліки) зараз, а важкі - потім, коли буде час." --- ## 1. Проблема без `startTransition()` До React 18 усі виклики `setState()` мали однаковий пріоритет. Якщо в UI виконувалась важка операція (наприклад, фільтрація великого списку), інтерфейс міг **підвисати**, поки React не закінчить рендер. ### Приклад без `startTransition()`: ```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 рендерить список на кожен символ - поле вводу **запізнюється**. --- ## 2. Рішення: `startTransition()` React 18 дозволяє позначити "важке" оновлення як *низькопріоритетне*: ```javascript import { startTransition } from 'react'; function handleChange(e) { const value = e.target.value; setQuery(value); // термінове (високий пріоритет) startTransition(() => { setResults(filterBigList(value)); // відкладене (низький пріоритет) }); } ``` Тепер: - React **миттєво оновить input** (високий пріоритет); - "рендер списку" виконає **пізніше**, коли потік вільний; - якщо користувач продовжить ввід, React **скасує** стару фільтрацію і запустить нову. --- ## 3. Як це працює всередині Коли React бачить `startTransition(callback)`: 1. React **ставить оновлення всередині callback в окрему чергу** - чергу **"transitions"** (низький пріоритет); 2. Усі звичайні `setState()` поза `startTransition` - залишаються **терміновими**; 3. React виконує термінові завдання спершу (наприклад, ввід тексту); 4. Потім, коли потік вільний, React **відновлює** виконання transition; 5. Якщо за цей час прийшло нове термінове оновлення, React **перериває transition** і починає нове (щоб інтерфейс був завжди актуальним). --- ## 4. Синтаксис і використання ### У функціональному компоненті: ```javascript import { startTransition } from 'react'; startTransition(() => { setState(...); // будь-яке низькопріоритетне оновлення }); ``` ### Або через хук: ```javascript const [isPending, startTransition] = useTransition(); ``` (ця версія дозволяє відстежувати статус очікування, `isPending`) --- ## 5. Приклад з `isPending` (через useTransition) ```javascript 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 && <span>Оновлення списку...</span>} <ResultsList items={results} /> </> ); } ``` Поведінка: - `setQuery()` оновлює поле одразу; - `setResults()` рендериться асинхронно; - `isPending` показує індикатор, поки transition не завершено. --- ## 6. Різниця між звичайним оновленням і transition | Характеристика | Звичайне оновлення (`setState`) | Transition (`startTransition`) | |---|---|---| | Пріоритет | Високий (терміновий) | Низький (відкладений) | | Може бути перервано | Ні | Так | | Коли виконується | Одразу | Коли є вільний час | | Використовується для | Вводу, кліків, анімацій | Фільтрації, завантаження, перебудови UI | | Впливає на UX | Може лагати | Плавний UI | --- ## 7. React сам вирішує пріоритети React ділить усі оновлення на два типи: - **Urgent (термінові)** - відбуваються від дій користувача (ввід, клік); - **Transition (перехідні)** - менш важливі, можна виконати пізніше. React виконує urgent-події **негайно**, а transitions - **у фоні**, **без блокування інтерфейсу**. --- ## 8. Нове в React 19 У **React 19** `startTransition()` став **розуміти async/await**: тепер можна дочекатися завершення асинхронних операцій усередині Transition. ```javascript await startTransition(async () => { const data = await fetch('/api/products').then(res => res.json()); setProducts(data); }); ``` Раніше (у React 18) `startTransition()` приймав лише синхронну функцію - асинхронний код потрібно було обгортати вручну. --- ## 9. Коли використовувати `startTransition()` Використовуй `startTransition()` для: - фільтрації / сортування / пошуку у великому списку; - дозавантаження даних після взаємодії; - зміни вкладок або маршрутів, якщо це вимагає рендеру великого дерева; - оновлень, не критичних до миттєвого UX. Не використовуй для: - подій кліку / фокусу / інпуту - вони мають бути **терміновими**; - дрібних UI-оновлень (іконки, лоадери тощо). --- ## Підсумок > `startTransition()` - це спосіб позначити оновлення стану як *низькопріоритетні*. > > React виконує їх **асинхронно й плавно**, щоб UI не зависав. > > Ідеально підходить для "важких" або нетермінових змін інтерфейсу. --- ### Коротка шпаргалка | Що робить | Ключова ідея | |---|---| | `startTransition(callback)` | Позначає оновлення як "нетермінові" | | "Заморожує" UI? | Ні - UI залишається відзивчивим | | Можна скасувати / призупинити | Так | | Працює лише в Concurrent Mode | Так (`createRoot()`) | | Повертає `Promise` (у React 19+) | Так | | Типові сценарії | Фільтрація, навігація, сортування, дозавантаження даних |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.