Skip to main content

Що робить React Query (TanStack Query)?

Коротко:

React Query (TanStack Query) - це "розумний менеджер серверних даних" для React, який бере на себе все: завантаження, кеш, рефетч, помилки, синхронізацію, оптимістичні оновлення тощо.

Він робить роботу з API реактивною, швидкою і безпечною, без ручного useEffect і useState.

Що робить React Query (TanStack Query)

React Query - це "клієнт даних", який керує завантаженням, кешуванням, оновленням і синхронізацією даних у React-застосунках.

Тобто:

  • ти описуєш як отримати дані (queryFn) і що це за дані (queryKey),
  • а React Query сам:
    • робить запит;
    • кешує результат;
    • оновлює UI при зміні даних;
    • повторно валідує кеш;
    • керує станами "loading", "error" і "stale";
    • синхронізує все при фокусі вікна, перемиканні вкладок тощо.

Коротко: "Server state manager"

React Query не замінює Redux / Zustand, тому що він не для client state (стану інтерфейсу), а для server state - даних, отриманих з API.

Тип стануПрикладДе зберігати
Client statemodal відкрита/закрита, обрана вкладкаuseState / Redux / Zustand
Server stateкористувачі, пости, замовлення, товариReact Query

Приклад базового використання

javascript
import { useQuery } from "@tanstack/react-query"; function UserProfile({ id }) { const { data, isLoading, error } = useQuery({ queryKey: ['user', id], queryFn: () => fetch(`/api/users/${id}`).then(res => res.json()), }); if (isLoading) return <p>Loading...</p>; if (error) return <p>Error loading user</p>; return <p>{data.name}</p>; }

React Query:

  • один раз робить fetch();
  • кешує результат за ключем ['user', id];
  • якщо компонент демонтується і знову з'явиться - дані вже будуть у кеші, без повторного запиту;
  • якщо фокус повернеться у вікно -> автоматично оновить дані.

Основні фічі

1. Кешування даних

React Query кешує дані в пам'яті (QueryClient) з гнучкими налаштуваннями:

javascript
<QueryClientProvider client={queryClient}> <App /> </QueryClientProvider>

Параметри:

javascript
useQuery({ staleTime: 5 * 60 * 1000, // 5 хвилин вважаються актуальними cacheTime: 10 * 60 * 1000, // через 10 хв кеш видаляється з пам'яті });

2. Stale-While-Revalidate

Показує кешовані (stale) дані миттєво, а паралельно робить запит за свіжими і оновлює UI після.

-> UX без "мигання" лоадерів.


3. Refetch on focus / reconnect

Якщо користувач згорнув вкладку, а потім повернувся:

  • React Query автоматично перезапитує дані (якщо вони "застаріли").
javascript
<QueryClientProvider client={new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: true } } })}>

4. Deduplication (дедуплікація запитів)

Якщо два компоненти викликають той самий запит:

javascript
useQuery({ queryKey: ['user', 1], queryFn: fetchUser }); useQuery({ queryKey: ['user', 1], queryFn: fetchUser });
  • React Query виконає тільки один запит, а обидва компоненти отримають однакові дані з кешу.

5. Mutations (POST / PUT / PATCH / DELETE)

Для зміни даних є useMutation():

javascript
import { useMutation, useQueryClient } from '@tanstack/react-query'; function UpdateUserButton({ id }) { const queryClient = useQueryClient(); const updateUser = useMutation({ mutationFn: (data) => fetch(`/api/users/${id}`, { method: 'PATCH', body: JSON.stringify(data), }), onSuccess: () => { // Після успішного оновлення інвалідуємо кеш queryClient.invalidateQueries(['user', id]); }, }); return ( <button onClick={() => updateUser.mutate({ name: 'Alex' })}> Update </button> ); }

6. Optimistic updates (оптимістичні оновлення)

Миттєво оновлює UI до відповіді сервера, а при помилці - відкочує.

javascript
const mutation = useMutation({ mutationFn: likePost, onMutate: async (postId) => { await queryClient.cancelQueries(['post', postId]); const prev = queryClient.getQueryData(['post', postId]); queryClient.setQueryData(['post', postId], old => ({ ...old, likes: old.likes + 1 })); return { prev }; }, onError: (_, postId, ctx) => { queryClient.setQueryData(['post', postId], ctx.prev); }, onSettled: (postId) => { queryClient.invalidateQueries(['post', postId]); }, });

7. Pagination, Infinite scroll, Prefetch

Вбудована підтримка пагінації і підвантаження сторінок:

javascript
useInfiniteQuery({ queryKey: ['posts'], queryFn: ({ pageParam = 1 }) => fetch(`/api/posts?page=${pageParam}`).then(r => r.json()), getNextPageParam: (lastPage) => lastPage.nextPage, });

8. Persist кешу

Можна зберігати кеш між сесіями:

javascript
import { persistQueryClient } from '@tanstack/react-query-persist-client'; persistQueryClient({ queryClient, persister: createSyncStoragePersister({ storage: window.localStorage }), });

-> при перезавантаженні дані не втрачаються, запити не повторюються.


Як це виглядає концептуально

React Query бере на себе:

javascript
ручний fetch() useEffect() useState() стан loading / error / success кешування та інвалідування повторні запити при фокусі все автоматично

Ключові концепції

ТермінЩо це
QueryЧитання даних (GET)
MutationЗміна даних (POST, PUT, DELETE)
Query KeyУнікальний ідентифікатор запиту в кеші
Query FunctionФункція, що виконує запит
Query ClientЦентральний менеджер кешу
InvalidationОновлення кешу після змін
Stale TimeЧас, поки дані вважаються свіжими
Cache TimeЧас, після якого дані видаляються з пам'яті

Підсумок

МожливістьЩо робить React Query
Автоматичні запитиробить і повторює fetch
Кешуваннязберігає дані за ключем
Оновлення данихrefetch при фокусі/зміні
Керування станамиisLoading, isError, isFetching, data
Оптимістичні оновленнямиттєвий UI-відгук
Інвалідація кешуоновлює після mutation
Deduplicationодин запит - декілька компонентів
Persist кешуміж вкладками/сесіями
Infinite Scroll / Paginationготові хуки
Без зайвого boilerplateбез useEffect/useState для запитів

Коротка відповідь

Для співбесіди
Premium

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