React / Data Fetching

TanStack Query

Zastąp useState + useEffect dla API calls — automatyczne caching, background refetch, optimistic updates i SSR hydration w Next.js.

useQuery
Server state
useMutation
Zapis danych
queryKey
Cache key
HydrationBoundary
SSR ready

6 kluczowych funkcji TanStack Query

Automatyczne zarządzanie server state — od cachowania przez background refresh po optimistic updates i infinite scroll.

Automatic Caching

Dane cachowane po queryKey, reużywane między komponentami

Konfiguracja: staleTime, gcTime

Domyślnie: 0ms staleTime, 5min gcTime

Background Refetch

Odśwież dane w tle gdy okno dostaje focus lub sieć wraca

Konfiguracja: refetchOnWindowFocus, refetchOnReconnect

Domyślnie: true

Automatic Retry

Ponów żądanie przy błędach z exponential backoff

Konfiguracja: retry, retryDelay

Domyślnie: 3 retries

Deduplication

Ten sam queryKey = jeden request, wiele subskrybentów

Konfiguracja: Automatyczne

Domyślnie: Zawsze

Optimistic Updates

Natychmiastowa aktualizacja UI przed potwierdzeniem serwera

Konfiguracja: onMutate + rollback

Domyślnie: Manualne

Infinite Queries

Pagination i infinite scroll z useInfiniteQuery

Konfiguracja: getNextPageParam, fetchNextPage

Domyślnie: Wbudowane

Często zadawane pytania

Co to jest TanStack Query (React Query) i dlaczego zastępuje useState + useEffect?

TanStack Query (dawniej React Query): biblioteka do zarządzania server state w React. Problem z useState + useEffect dla API calls: brak automatycznego cachowania. Brak deduplication requestów. Brak automatic refetch (po focus, po reconnect). Brak background refresh. Brak loading/error states zarządzanych globalnie. Brak pagination/infinite scroll helpers. TanStack Query rozwiązuje te wszystkie problemy. Kluczowe koncepty: Query: operacja odczytu danych (GET). useQuery(queryKey, queryFn). queryKey: unikalny identyfikator query (array). queryFn: async function zwracająca dane. Mutation: operacja zapisu (POST/PUT/DELETE). useMutation(mutationFn). Automatyczne features: Caching: dane cachowane po queryKey. Stale-while-revalidate: pokaż stale dane, odśwież w tle. Auto-refetch: po window focus, po network reconnect. Retry: automatyczne retry przy błędach (3 razy z backoff). Deduplication: ten sam queryKey -> jeden request. Background refetch: odśwież cache w tle. Loading states: isLoading, isFetching, isError, isSuccess. Devtools: @tanstack/react-query-devtools. Wizualizacja cache, queryów, stale time.

TanStack Query — queryKey, staleTime, gcTime i cache invalidation?

queryKey: tablica identyfikująca query. ['users'] — lista użytkowników. ['users', userId] — konkretny user. ['users', {status: 'active', page: 1}] — filtrowanie. Granularna invalidacja: queryClient.invalidateQueries({queryKey: ['users']}) — inwaliduj wszystkie usery. queryClient.invalidateQueries({queryKey: ['users', userId]}) — tylko konkretny. staleTime: jak długo dane są 'świeże'. 0 (domyślny) — zawsze stale (zawsze refetch przy użyciu). Infinity — nigdy stale (refetch tylko manualnie). 5 * 60 * 1000 — 5 minut. gcTime (dawniej cacheTime): jak długo nieużywane dane w cache. 5 * 60 * 1000 (domyślny) — 5 minut. refetchInterval: polling (np. co 30 sekund). enabled: boolean — czy query jest aktywne. enabled={!!userId} — query tylko gdy userId dostępne. Prefetching: queryClient.prefetchQuery(['user', id], fetchUser). Np. na hover linku. Invalidation po mutation: onSuccess: () => queryClient.invalidateQueries({queryKey: ['users']}). Stary cache uważany za stale -> refetch. Optimistic Updates: onMutate — aktualizuj cache optymistycznie. onError — rollback jeśli mutation fail. onSettled — synchronizuj z serwerem. Pagination: keepPreviousData (v4) / placeholderData (v5). Infinite Query: useInfiniteQuery. getNextPageParam. fetchNextPage(). Wszystkie strony w pages array.

useMutation i synchronizacja ze stanem serwera?

useMutation: dla operacji zapisu. const mutation = useMutation({mutationFn: (data) => api.createUser(data), onSuccess: (data, variables, context) => {...}, onError: (error, variables, context) => {...}, onSettled: (data, error, variables, context) => {...}}). Wywołanie: mutation.mutate(formData). mutation.mutateAsync(formData) — zwraca Promise. mutation.isPending, mutation.isError, mutation.isSuccess. Lifecycle callbacks: onSuccess — zapis do cache, invalidacja, toast. onError — error handling, rollback. onSettled — cleanup (zawsze). Optimistic Updates: onMutate: (variables) => {await queryClient.cancelQueries(['todos']). const previousTodos = queryClient.getQueryData(['todos']). queryClient.setQueryData(['todos'], old => [...old, {id: 'temp', ...variables}]). return {previousTodos}}. onError: (err, variables, context) => queryClient.setQueryData(['todos'], context.previousTodos). onSettled: () => queryClient.invalidateQueries(['todos']). Server-side mutations: Next.js Server Actions + useMutation. Formularz -> Server Action -> onSuccess -> invalidate. Form libraries: React Hook Form + useMutation. Zodios: Zod + axios + React Query. Full-stack type safety. tRPC + TanStack Query: automatycznie generowane hooki per endpoint. Type-safe end-to-end.

TanStack Query w Next.js — SSR, hydration i Server Components?

TanStack Query z SSR: prefetch na serwerze -> hydrate na kliencie. Podejście 1 (pages router): getServerSideProps: await queryClient.prefetchQuery(...). dehydrate(queryClient) -> props. Client: HydrationBoundary + QueryClientProvider. Podejście 2 (app router): Server Components: fetchuj dane bezpośrednio (bez React Query). Client Components: używaj React Query dla interaktywnych danych. Prefetch w Server Component: await queryClient.prefetchQuery(['users'], fetchUsers). <HydrationBoundary state={dehydrate(queryClient)}>. Zalety: dane dostępne natychmiast po hydration (bez loading spinner). SEO-friendly. Streaming z React Suspense: Suspense boundary + useQuery. Dane streamowane z serwera. Initial data nie jest undefined. Next.js cache (app router): fetch() z {cache: 'force-cache'} — cache na serwerze. React Query cache — cache po stronie klienta. Dwa oddzielne poziomy cache. Stale time config: 0 dla server-critical. Infinity dla static data. Podejście hybrydowe 2024: Server Components dla static data (SEO, first load). Client Components + React Query dla interactive/real-time data. Nie używaj React Query w Server Components — use fetch() directly.

TanStack Query DevTools i testowanie — jak debugować?

TanStack Query DevTools: import {ReactQueryDevtools} from '@tanstack/react-query-devtools'. Wizualizacja: wszystkie aktywne queries. Stan per query (fetching/stale/fresh/inactive). Query data podgląd. Cache zawartość. Refetch per query. Invalidate per query. Filtrowanie queryów. Konfiguracja: domyślnie tylko w development. buttonPosition 'bottom-right' | 'bottom-left'. initialIsOpen — otwarte przy start. Custom logger: QueryClient({defaultOptions: {queries: {onError: (err) => logger.error(err)}}}). Logging w mutations: onError na poziomie QueryClient. Testing TanStack Query: React Testing Library + jest. mockServiceWorker (MSW) — interceptuj HTTP requests. Zamiast mockować fetch — MSW zwraca właściwe dane. Testy komponentów: renderWithClient — wrapper z QueryClient. waitFor — poczekaj na async operation. screen.findByText — async query. QueryClient per test — nie współdziel stanu. Jest mock: jest.mock('react-query', ...) — rzadko używaj. MSW jest lepszy. TanStack Query hooks testing: renderHook({wrapper: createWrapper()}). Błędy w testach: QueryCache: silent mode w testach. console.error mock. Error boundary w testach. Performance: React DevTools Profiler. Why did I render? npm package. Avoid getQueryData w render — może powodować niepotrzebne subskrypcje.

Kontakt

Skontaktuj się z nami

Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

Wyślij zapytanie

Bezpłatna wycena w 24h
Bez zobowiązań
Indywidualne podejście
Ekspresowa realizacja

Telefon

+48 790 814 814

Pon-Pt: 9:00 - 18:00

Email

adam@fotz.pl

Odpowiadamy w ciągu 24h

Adres rejestrowy

Poznańska 117/11

62-023 Kamionki · obsługa zdalna

Godziny pracy

Pon - Pt9:00 - 18:00
Sob - NdzZamknięte

Wolisz porozmawiać?

Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

Zadzwoń teraz