Що робить useDeferredValue()?
Що робить 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} />
</>
);
}Що відбувається:
queryоновлюється одразу - поле вводу чуйне.deferredQueryоновлюється трохи пізніше - React дочекається, поки звільниться потік.- Поки фільтрація виконується, можна навіть показати індикатор завантаження.
Різниця між 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)-> "Не оновлюй це значення одразу. Почекай, поки користувач перестане активно взаємодіяти."
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.