Skip to main content

Що робить 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} /> </> ); }

Що відбувається:

  1. query оновлюється одразу - поле вводу чуйне.
  2. deferredQuery оновлюється трохи пізніше - React дочекається, поки звільниться потік.
  3. Поки фільтрація виконується, можна навіть показати індикатор завантаження.

Різниця між useTransition і useDeferredValue

ОсобливістьuseTransitionuseDeferredValue
Що робитьОбгортає оновлення стануВідкладена версія значення
Використовується деУ місці, де викликаєш 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

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.