Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить startTransition()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Функція **`startTransition()`** дозволяє позначити оновлення стану (`setState`) як **неспішне** (low-priority update). **Ключове:** це дає React змогу спочатку виконати термінові оновлення (введення тексту, кліки), а потім обробити другорядні (фільтрація, сортування, рендер списків тощо).Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `startTransition()` Функція `startTransition()` дозволяє позначити оновлення стану (`setState`) як **неспішне** (low-priority update). Це дає React можливість: - **призупиняти** або **відкладати** важкий рендер, - **спочатку** виконати важливі оновлення (наприклад, введення тексту, кліки), - а потім - обробити "другорядні" (фільтрація, сортування, рендер списків тощо). --- ## Синтаксис ```javascript import { startTransition } from "react"; startTransition(() => { // тут викликаємо setState }); ``` або з хуком: ```javascript const [isPending, startTransition] = useTransition(); startTransition(() => { // те саме }); ``` --- ## Приклад Уяви: користувач вводить текст у поле пошуку, а ти фільтруєш великий масив даних - 10 000 елементів. ### Без `startTransition` (UI "фризиться") ```javascript function Search() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const handleChange = (e) => { const value = e.target.value; setQuery(value); setResults(filterBigArray(value)); // важка операція }; return ( <> <input value={query} onChange={handleChange} /> <List data={results} /> </> ); } ``` Проблема: - Кожен символ в `input` викликає *рендер списку*. - React зайнятий, введення **гальмує**. --- ### З `startTransition` ```javascript import { startTransition } from "react"; function Search() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const handleChange = (e) => { const value = e.target.value; setQuery(value); // терміново (high-priority) startTransition(() => { setResults(filterBigArray(value)); // не терміново (low-priority) }); }; return ( <> <input value={query} onChange={handleChange} /> <List data={results} /> </> ); } ``` Тепер React: - Спочатку миттєво оновлює `query`, щоб поле вводу не гальмувало. - Потім, коли є час, перераховує `results`. UI залишається плавним і чутливим. --- ## Що відбувається під капотом | Етап | Що робить React | |---|---| | Ти викликаєш `startTransition(() => setState())` | React позначає оновлення як "низькопріоритетне" | | Користувач продовжує взаємодію | Термінові оновлення (`setQuery`) виконуються одразу | | React завершує термінові завдання | Після цього запускає "важке" обчислення | | Коли готово - UI оновлюється | Без лагів і фризів | --- ## Приклад з індикатором ```javascript import { useTransition } from "react"; function FilterList({ data }) { const [filter, setFilter] = useState(""); const [filtered, setFiltered] = useState(data); const [isPending, startTransition] = useTransition(); const handleChange = (e) => { const value = e.target.value; setFilter(value); startTransition(() => { const result = data.filter(item => item.includes(value)); setFiltered(result); }); }; return ( <> <input value={filter} onChange={handleChange} /> {isPending && <p>Фільтруємо...</p>} <ul> {filtered.map((item, i) => <li key={i}>{item}</li>)} </ul> </> ); } ``` Поки триває фільтрація, `isPending = true`, React показує "Фільтруємо...", і при цьому **введення залишається миттєвим** - без лагів. --- ## Що можна робити всередині `startTransition` Можна: - викликати `setState` (навіть декілька разів); - обчислювати похідні дані (наприклад, фільтрувати, сортувати); - запускати мемоізацію, якщо вона не блокує інтерфейс. Не можна: - використовувати асинхронний `await`; - ставити таймери (`setTimeout`) - React має контролювати все сам. --- ## Важливо пам'ятати | Особливість | Пояснення | |---|---| | Працює лише в React 18+ | Оскільки потребує Concurrent Rendering | | Не гарантує миттєве виконання | React сам вирішує, коли почати | | Не скасовує інші оновлення | Просто знижує пріоритет | | Працює **лише зі станом React** | Не керує зовнішніми async-запитами | | Можна використовувати **поза компонентом** | `startTransition` доступний напряму з `react` | --- ## Підсумок | Питання | Відповідь | |---|---| | Що робить `startTransition()` | Позначає оновлення стану як "неспішне", щоб React міг призупинити або відкласти його | | Коли React виконує його | Після всіх термінових оновлень (введення, кліки, hover) | | Навіщо потрібно | Щоб інтерфейс не "фризився" при важких обчисленнях або рендерах | | Що повертає | Нічого (керується разом з `isPending` з `useTransition`) | | Коли використовувати | Для фільтрації, навігації, сортування, оновлень великих списків | | Коли не використовувати | Для звичайних `setState` і асинхронних API-запитів | --- **Головна ідея:** > `startTransition()` - це спосіб сказати React: > "Нехай інтерфейс залишається чутливим, > а це оновлення можеш зробити трохи пізніше."Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.