TanStack Query: Майстерність Керування Станом Сервера

Встановлення та Налаштування: Фундамент

Правильний старт — половина успіху. У цій главі ми не просто встановимо бібліотеку, а налаштуємо її так, щоб вона працювала на нас, а не проти нас. Ми також підключимо DevTools — інструмент, без якого робота з TanStack Query нагадує ходіння в темряві.

Встановлення та Налаштування: Фундамент

Правильний старт — половина успіху. У цій главі ми не просто встановимо бібліотеку, а налаштуємо її так, щоб вона працювала на нас, а не проти нас. Ми також підключимо DevTools — інструмент, без якого робота з TanStack Query нагадує ходіння в темряві.

1. Інсталяція

TanStack Query розбитий на модульні пакети. Нам знадобиться основний пакет для React та DevTools.

npm install @tanstack/react-query @tanstack/react-query-devtools
npm install -D @tanstack/eslint-plugin-query
Ми також встановлюємо eslint-plugin-query. Він допоможе вам уникати поширених помилок та дотримуватися best practices ще на етапі написання коду.

2. Створення QueryClient

Серцем бібліотеки є QueryClient. Це клас, який керує QueryCache (кешем запитів) та MutationCache (кешем мутацій).

Створимо файл для налаштування клієнта. Це хороша практика — виносити конфігурацію окремо.

lib/queryClient.ts
import { QueryClient } from '@tanstack/react-query';

// Створюємо екземпляр клієнта
export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      // ⚠️ Важливо: тут ми визначаємо глобальну поведінку
      staleTime: 1000 * 60, // 1 хвилина
      gcTime: 1000 * 60 * 5, // 5 хвилин (раніше cacheTime)
      retry: 1, // Кількість повторних спроб при помилці
      refetchOnWindowFocus: false, // Вимкнути авто-оновлення при фокусі вікна (опціонально)
    },
  },
});

Розбір defaultOptions

Це критичний момент. За замовчуванням TanStack Query налаштований "агресивно":

  • staleTime: 0: Дані вважаються застарілими миттєво. Це означає, що будь-який повторний рендер або перефокусування вікна спровокує запит.
  • refetchOnWindowFocus: true: Користувач перемкнув вкладку і повернувся — запит пішов.

Для багатьох додатків це занадто. Встановлення staleTime: 1000 * 60 (1 хвилина) — це розумний компроміс. Це означає: "Якщо я отримав дані менше хвилини тому, не роби новий запит, навіть якщо компонент перемонтувався".

3. Підключення Провайдера

Тепер потрібно огорнути наш додаток у QueryClientProvider і передати туди створений клієнт. Це зробить кеш доступним для будь-якого компонента через React Context.

Також тут ми підключаємо DevTools.

main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { queryClient } from './lib/queryClient'; // Імпорт нашого налаштованого клієнта
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
      
      {/* 
        DevTools з'являться як плаваюча кнопка (квітка) внизу екрану.
        initialIsOpen={false} означає, що вони будуть згорнуті за замовчуванням.
        В production-build цей код автоматично виріжеться (завдяки tree-shaking),
        але краще перевірити налаштування вашого бандлера.
      */}
      <ReactQueryDevtools initialIsOpen={false} buttonPosition="bottom-right" />
    </QueryClientProvider>
  </React.StrictMode>,
);

4. Сила DevTools

Чому DevTools — це не опція, а необхідність?

Уявіть, що ви працюєте з базою даних, але у вас немає GUI-клієнта (як DBeaver чи pgAdmin), і ви можете лише здогадуватися, що там лежить. Жахливо, правда?

DevTools показують вам "нутрощі" QueryCache.

  • Status: Ви бачите статус кожного запиту: Fresh (зелений), Stale (жовтий), Fetching (синій), Inactive (сірий).
  • Data Explorer: Ви можете переглядати JSON-відповідь сервера прямо в браузері.
  • Actions: Ви можете вручну натиснути "Refetch", "Invalidate" або "Reset" для будь-якого запиту, щоб протестувати поведінку UI.
  • Network Throttle: Хоча це є в Chrome DevTools, тут зручніше бачити, як поводиться саме Query при повільній мережі.
Натисніть на логотип TanStack Query в вашому додатку після запуску. Якщо ви бачите список запитів з їхніми ключами — вітаємо, ви все налаштували правильно!

5. Налаштування ESLint

Якщо ви використовуєте ESLint, додайте плагін у ваш конфіг. Це врятує вас від дурних помилок, наприклад, коли ви забули додати ключ у масив залежностей queryKey.

.eslintrc.cjs
module.exports = {
  // ...
  plugins: ['@tanstack/query'],
  extends: [
    // ...
    'plugin:@tanstack/eslint-plugin-query/recommended',
  ],
};

Що він перевіряє:

  • Чи є queryKey валідним масивом.
  • Чи використовуєте ви застарілі методи.
  • Чи правильно ви працюєте з асинхронністю.

6. TypeScript

TanStack Query написаний на TypeScript і надає чудову підтримку типів "з коробки".

Вам майже ніколи не треба буде явно типізувати useQuery, якщо ваша функція-фечер (queryFn) правильно типізована.

// Якщо ця функція повертає Promise<User[]>
const fetchUsers = async (): Promise<User[]> => { ... }

// То useQuery автоматично знає, що data - це User[] | undefined
const { data } = useQuery({ queryKey: ['users'], queryFn: fetchUsers });

Ми детальніше розглянемо типізацію в наступних розділах.

React 18 Strict Mode

Ви можете помітити, що в режимі розробки (npm run dev) ваші запити виконуються двічі.

Це нормальна поведінка React 18 Strict Mode. React спеціально монтує, демонтує і знову монтує ваш компонент, щоб перевірити, чи правильно ви працюєте з ефектами (cleanup).

TanStack Query обробляє це коректно (дедуплікація), але в Network tab ви можете бачити два запити, якщо вони дуже швидкі. Не лякайтеся, на production (після npm run build) цього не буде.

Далі: Основи запитів та Query Keys

Copyright © 2026