Оптимізація React-додатків: Використовуємо useTransition, useDeferredValue та useOptimistic для плавного UI
Сучасні React-додатки часто мають складний інтерфейс із динамічними елементами, що взаємодіють із користувачем у реальному часі. Оптимізація продуктивності таких додатків є важливою задачею, особливо для забезпечення плавного користувацького досвіду. У цьому контексті React надає корисні інструменти: useTransition
, useDeferredValue
та useOptimistic
. Розглянемо, як їх використовувати.
Що таке useTransition
?
useTransition
— це хук, який дозволяє позначати частину оновлень у React як “незначущі”. Це означає, що такі оновлення не будуть блокувати основний інтерфейс користувача, навіть якщо вони займають більше часу.
Приклад використання useTransition
Уявімо, що у нас є додаток із великим списком, який користувач може фільтрувати:
import { useState, useTransition } from 'react';
function FilterableList({ items }) {
const [filter, setFilter] = useState('');
const [filteredItems, setFilteredItems] = useState(items);
const [isPending, startTransition] = useTransition();
const handleFilterChange = (e) => {
const value = e.target.value;
setFilter(value);
startTransition(() => {
const newFilteredItems = items.filter(item => item.includes(value));
setFilteredItems(newFilteredItems);
});
};
return (
<div>
<input value={filter} onChange={handleFilterChange} placeholder="Фільтрувати..." />
{isPending && <div>Завантаження...</div>}
<ul>
{filteredItems.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</div>
);
}
Як це працює
startTransition
використовується для запуску “незначущих” оновлень.isPending
показує, чи триває транзакція.- Основний інтерфейс, наприклад, введення тексту у поле, залишається плавним, навіть якщо фільтрація займає багато часу.
Що таке useDeferredValue
?
useDeferredValue
дозволяє відкладати оновлення значення до моменту, коли браузер буде готовий виконати його, не впливаючи на продуктивність основного інтерфейсу.
Приклад використання useDeferredValue
Припустимо, що у нас є компонент для пошуку, який відображає результати в режимі реального часу:
import { useState, useDeferredValue } from 'react';
function Search({ items }) {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const results = items.filter(item => item.includes(deferredQuery));
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Пошук..."
/>
<ul>
{results.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</div>
);
}
Як це працює
useDeferredValue
створює відкладену версію значенняquery
.- Це дозволяє браузеру спочатку обробити термінові оновлення, такі як введення тексту, а вже потім виконати пошук.
Що таке useOptimistic
?
useOptimistic
— це хук, який допомагає створювати оптимістичні оновлення стану. Це означає, що зміни в UI будуть відображені одразу, ще до завершення операції (наприклад, запиту на сервер).
Приклад використання useOptimistic
Припустимо, у нас є кнопка, яка додає елемент до списку:
import { useOptimistic } from 'react';
function OptimisticList() {
const [list, setList] = useOptimistic([], (prev, newItem) => [...prev, newItem]);
const handleAddItem = async () => {
const newItem = `Item ${list.length + 1}`;
setList(newItem);
// Симуляція запиту на сервер
await fetch('/api/add-item', {
method: 'POST',
body: JSON.stringify({ item: newItem }),
});
};
return (
<div>
<button onClick={handleAddItem}>Додати елемент</button>
<ul>
{list.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</div>
);
}
Як це працює
useOptimistic
дозволяє відобразити новий елемент у списку одразу після натискання кнопки.- Якщо сервер поверне помилку, ви можете відкотити зміни.
Коли використовувати ці інструменти?
useTransition
: коли ви хочете розділити важкі обчислення або оновлення стану від термінових подій, таких як введення тексту.useDeferredValue
: для покращення продуктивності компонентів, які залежать від значення, що часто змінюється.useOptimistic
: для створення швидкої та інтерактивної взаємодії з користувачем у ситуаціях, коли серверна операція може займати час.
Висновок
React пропонує потужні інструменти для оптимізації взаємодії з користувачем, особливо у додатках, де продуктивність є ключовою. Використання useTransition
, useDeferredValue
та useOptimistic
дозволяє забезпечити плавний та швидкий UI, одночасно спрощуючи обробку складних обчислень та запитів. Застосовуючи ці інструменти у ваших проектах, ви зможете значно покращити користувацький досвід та продуктивність вашого додатку.