Dev Highlights

Доки по разработке

This project is maintained by teniryte

1. Установка и настройка

Что ставить

npm install @tanstack/react-query
npm install -D @tanstack/react-query-devtools

Опциональные пакеты:

Минимальная настройка

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 30_000,
      gcTime: 5 * 60_000,
      retry: 3,
    },
  },
})

export function AppProviders({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  )
}

Главная идея: в браузере у вас почти всегда должен жить один стабильный QueryClient, а не новый экземпляр на каждый рендер.

Важные значения по умолчанию

Рекомендуемый QueryClient

import { QueryClient } from '@tanstack/react-query'

export function makeQueryClient() {
  return new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 60_000,
        gcTime: 10 * 60_000,
        retry: (failureCount, error) => {
          if (error instanceof Response && error.status < 500) return false
          return failureCount < 3
        },
      },
      mutations: {
        retry: 0,
      },
    },
  })
}

Практика:

Безопасный провайдер для SSR и App Router

Официальный паттерн для React 18+/Next.js App Router: новый клиент на сервере, singleton в браузере.

'use client'

import {
  isServer,
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'

function makeQueryClient() {
  return new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 60_000,
      },
    },
  })
}

let browserQueryClient: QueryClient | undefined

function getQueryClient() {
  if (isServer) return makeQueryClient()
  if (!browserQueryClient) browserQueryClient = makeQueryClient()
  return browserQueryClient
}

export function Providers({ children }: { children: React.ReactNode }) {
  const queryClient = getQueryClient()

  return (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  )
}

Почему так:

Devtools

import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

<QueryClientProvider client={queryClient}>
  <App />
  {import.meta.env.DEV ? <ReactQueryDevtools initialIsOpen={false} /> : null}
</QueryClientProvider>

Настройка под разные типы данных

Чего избегать

Чек-лист