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.

    Czytaj dalej

    Powiązane artykuły

    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

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

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

    Wolisz porozmawiać?

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

    Zadzwoń teraz