Синхронізація Даних: Життєвий Цикл Запиту
Синхронізація Даних: Життєвий Цикл Запиту
Одна з найскладніших речей для розуміння в TanStack Query — це те, як і коли він вирішує оновити дані. "Чому воно знову робить запит?", "Чому дані зникли?" — типові питання.
У цій главі ми розберемо state machine (машину станів), яка живе всередині кожного запиту.
Стани Запиту
Кожен запит у будь-який момент часу перебуває в одному з цих станів:
- Fetching: Дані завантажуються (в польоті).
- Fresh (Свіжі): Дані актуальні. Query не буде намагатися їх оновити, навіть якщо ви попросите.
- Stale (Застарілі): Дані є, але вони "протухли". Query поверне їх вам, але у фоні спробує оновити.
- Inactive: Цей запит зараз не використовується жодним компонентом.
- Deleted: Видалено з пам'яті збирачем сміття (Garbage Collector).
staleTime vs gcTime
Це два найважливіші налаштування, які ви повинні розрізняти.
staleTime (Час Свіжості)
Питання: "Скільки часу дані вважаються ідеальними?"
- Default:
0(нуль). - Сенс: За замовчуванням дані стають застарілими миттєво після отримання.
- Поведінка:
- Якщо
staleTime: 0: При кожному вході на сторінку або фокусі вікна будеbackground refetch. - Якщо
staleTime: 5000(5 сек): Протягом 5 секунд після запиту дані вважаються свіжими. Жодних запитів не буде, навіть якщо ви перемонтуєте компонент 100 разів.
- Якщо
staleTime: Infinity або велике значення (наприклад, 10 хвилин).useQuery({
queryKey: ['settings'],
queryFn: fetchSettings,
staleTime: 1000 * 60 * 10, // 10 хвилин
});
gcTime (Garbage Collection Time)
Раніше відомий як cacheTime.
Питання: "Скільки часу тримати дані в пам'яті, якщо їх ніхто не бачить?"
- Default:
5 хвилин. - Сенс: Коли останній компонент, що використовував ці дані, демонтується (unmount), запит переходить у стан
Inactive. Таймер запускається. - Поведінка:
- Якщо користувач повернеться на сторінку через 2 хвилини: Дані миттєво з'являться з кешу. Таймер скинеться.
- Якщо користувач повернеться через 6 хвилин: Даних немає. Буде "hard loading" (скелетон).
gcTime не має нічого спільного з тим, коли робити запит. Воно лише про звільнення пам'яті.Тригери Оновлення (Refetch Triggers)
Коли дані знаходяться у стані Stale, TanStack Query чекає на "подію", щоб їх оновити.
refetchOnWindowFocus(Default:true)- Коли користувач перемикає вкладку браузера і повертається.
- Це гарантує, що користувач завжди бачить актуальні дані після повернення до роботи.
refetchOnMount(Default:true)- Коли компонент монтується. Якщо дані Stale — оновити.
refetchOnReconnect(Default:true)- Коли зник і знову з'явився інтернет.
Як вимкнути "зайві" запити?
Якщо вас дратує, що запити літають постійно (наприклад, під час розробки), ви можете налаштувати це глобально або локально.
// Локально для одного запиту
useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
refetchOnWindowFocus: false, // Не оновлювати при фокусі
staleTime: 1000 * 60, // Не оновлювати частіше ніж раз на хвилину
})
Polling (Інтервальне Оновлення)
Іноді вам потрібно оновлювати дані кожні N секунд (наприклад, ціни на біржі або статус чату).
useQuery({
queryKey: ['stock-price'],
queryFn: fetchPrice,
// Оновлювати кожні 2 секунди
refetchInterval: 2000,
// Навіть якщо вкладка браузера не активна (background)
refetchIntervalInBackground: true,
})
Статус fetchStatus
У v4/v5 з'явився новий проперті fetchStatus, який працює в парі з status.
status: pending | error | success (Про дані)
fetchStatus: fetching | paused | idle (Про мережу)
Сценарій: Ви зробили запит, але інтернет зник.
status:pending(даних ще немає).fetchStatus:paused(запит на паузі, чекає мережі).
Це дозволяє показувати UI типу "Waiting for connection...", замість простого спіннера, який крутиться вічно.
const { status, fetchStatus } = useQuery(...);
if (status === 'pending' && fetchStatus === 'paused') {
return <div>No Internet connection...</div>;
}
Основи Запитів та Магія Ключів
Тепер, коли ми маємо налаштований інструмент, час навчитися ним користуватися. У цій главі ми розберемо useQuery — основний хук, який ви будете використовувати у 90% випадків.
Мутації та Інвалідація: Зміна Даних
Досі ми лише читали дані (GET). Але веб-додатки — це про взаємодію. Ми хочемо створювати, оновлювати та видаляти дані (POST, PUT, DELETE).