Клієнтський стан належить інтерфейсу: відкрите модальне вікно, текст у полі, обрана вкладка. Він живе в браузері, і застосунок - його єдиний власник.
Серверний стан - копія даних, що живуть на сервері: список замовлень, профіль, вакансії. Його особливості:
- може змінитися без участі вашого застосунку (інший користувач, фонова задача);
- потребує завантаження, кешування, повторних запитів, обробки помилок;
- може бути застарілим у будь-який момент.
Зберігати його в useState чи глобальному сторі - означає вручну писати кеш, стани завантаження, інвалідацію й дедуплікацію запитів.
TanStack Query бере це на себе:
import { useQuery } from '@tanstack/react-query';
function Orders({ status }) {
const { data, isPending, error } = useQuery({
queryKey: ['orders', { status }],
queryFn: () => fetch(`/api/orders?status=${status}`).then((r) => r.json()),
staleTime: 30_000,
});
if (isPending) return <Spinner />;
if (error) return <ErrorMessage error={error} />;
return <OrderList orders={data} />;
}
Що дає:
- кеш за ключем (
queryKey): повернення на сторінку показує дані миттєво, а оновлення йде у фоні; - дедуплікація: десять компонентів з тим самим ключем - один запит;
- stale-while-revalidate: застарілі дані показуються, поки завантажуються свіжі;
- повторні запити при поверненні на вкладку, відновленні мережі, з інтервалом;
- повтори при помилках з затримкою;
- мутації (
useMutation) з інвалідацією кешу й оптимістичними оновленнями; - скасування застарілих запитів і відсутність гонитви.
Ключові налаштування:
staleTime- скільки даних вважаються свіжими (за замовчуванням 0 - застарілі одразу, тож повторний запит при кожному монтуванні). Для більшості даних варто задати секунди чи хвилини;gcTime- скільки невикористовувані дані лишаються в кеші;- ключ має містити всі параметри запиту - інакше різні запити ділитимуть один кеш.
Розподіл відповідальності: серверний стан - TanStack Query (чи SWR, RTK Query, завантажувачі фреймворку), клієнтський - useState, Context чи невеликий стор. Багато застосунків після переходу виявляють, що глобальний стор їм майже не потрібен.