Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить useDeferredValue()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`useDeferredValue()` відкладає (деферить) оновлення якогось значення, дозволяючи React спершу відрендерити термінові оновлення, а вже потім - "неспішні". **Ключове:** `useDeferredValue` використовує той самий механізм, що і `startTransition` - React позначає оновлення як "не термінове" (low-priority), тільки ти сам цим явно не керуєш, React сам вирішує, коли наздогнати значення.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `useDeferredValue()` `useDeferredValue()` відкладає (деферить) оновлення якогось значення, дозволяючи React **спершу відрендерити термінові оновлення**, а вже потім - "неспішні". > Простіше кажучи: > `useDeferredValue()` каже React: > **"Не поспішай оновлювати це значення, зроби це, коли буде вільний час."** --- ## Синтаксис ```javascript const deferredValue = useDeferredValue(value); ``` - `value` - звичайний стан або змінна; - `deferredValue` - "відкладена" версія цього значення, яка оновиться трохи пізніше, коли React закінчить термінові рендери. --- ## Приклад: пошук по великому списку ### Без `useDeferredValue` ```javascript function Search({ data }) { const [query, setQuery] = useState(""); const filtered = data.filter((item) => item.includes(query)); // важко return ( <> <input value={query} onChange={(e) => setQuery(e.target.value)} /> <List items={filtered} /> </> ); } ``` Проблема: - Кожне введення символу викликає фільтрацію всієї колекції. - UI гальмує, "лаг" при наборі тексту. --- ### З `useDeferredValue` ```javascript import { useDeferredValue } from "react"; function Search({ data }) { const [query, setQuery] = useState(""); const deferredQuery = useDeferredValue(query); // відкладаємо обробку const filtered = data.filter((item) => item.includes(deferredQuery)); return ( <> <input value={query} onChange={(e) => setQuery(e.target.value)} /> <List items={filtered} /> </> ); } ``` Що відбувається: 1. `query` оновлюється **одразу** - поле вводу чуйне. 2. `deferredQuery` оновлюється **трохи пізніше** - React дочекається, поки звільниться потік. 3. Поки фільтрація виконується, можна навіть показати індикатор завантаження. --- ## Різниця між `useTransition` і `useDeferredValue` | Особливість | `useTransition` | `useDeferredValue` | |---|---|---| | Що робить | Обгортає **оновлення стану** | Відкладена версія **значення** | | Використовується де | У місці, де викликаєш `setState` | У місці, де використовуєш значення | | Повертає | `[isPending, startTransition]` | `deferredValue` | | Керування | Ти сам вирішуєш, що "відкласти" | React сам відкладає оновлення | | Складність | Потрібно обгортати логіку | Дуже просто - 1 рядок | По суті: - `useTransition` -> відкладає **дію (setState)**. - `useDeferredValue` -> відкладає **результат (value)**. --- ## Приклад: фільтрація з індикатором завантаження ```javascript import { useDeferredValue } from "react"; function FilteredList({ items }) { const [query, setQuery] = useState(""); const deferredQuery = useDeferredValue(query); const filtered = items.filter((item) => item.toLowerCase().includes(deferredQuery.toLowerCase()) ); const isStale = query !== deferredQuery; // оновлення ще не наздогнало return ( <> <input value={query} onChange={(e) => setQuery(e.target.value)} /> {isStale && <p>Фільтрація...</p>} <List items={filtered} /> </> ); } ``` Поведінка: - При введенні тексту поле реагує миттєво. - Відмальовування великого списку трохи відкладається. - "Фільтрація..." показується, поки `deferredQuery` ще не оновився. --- ## Коли використовувати `useDeferredValue()` | Коли | Чому | |---|---| | Важка фільтрація або сортування за введеним значенням | Щоб не гальмував ввід | | Рендер великого списку або таблиці | Щоб відмальовування не блокувало UI | | Компонент отримує дороге проп-значення | Щоб React не перераховував його миттєво | | Хочеш плавне оновлення, але не хочеш ускладнювати код `useTransition` | Це "короткий шлях" до тієї самої мети | --- ## Коли **не потрібно** використовувати | Випадок | Чому | |---|---| | Оновлення легкі | React і так справляється | | Немає затримок при введенні | Надлишково | | Потрібне миттєве відображення | `useDeferredValue` спеціально робить *не миттєво* | | Для асинхронних запитів | Краще `useEffect` / `React Query` | --- ## Під капотом `useDeferredValue` використовує той самий механізм, що і `startTransition`: React позначає оновлення як **"не термінове" (low-priority)**. Різниця в тому, що: - ти **не керуєш** цим явно, - React **сам вирішує**, коли наздогнати значення. --- ## Підсумок | Питання | Відповідь | |---|---| | Що робить `useDeferredValue()` | Повертає відкладену версію значення, яка оновлюється з низьким пріоритетом | | Навіщо потрібен | Щоб інтерфейс залишався чуйним при важких рендерах | | Коли використовувати | Коли рендер або обчислення залежать від часто оновлюваного стану | | Коли не використовувати | Якщо оновлення легкі або повинні бути миттєвими | | Аналогія | Як `useTransition`, тільки "в один рядок" | --- **Головна ідея:** > `useDeferredValue(value)` -> "Не оновлюй це значення одразу. > Почекай, поки користувач перестане активно взаємодіяти."Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.