Installazione e Configurazione
Installazione
Per iniziare con TanStack Query in un progetto React, installa il pacchetto principale:
npm install @tanstack/react-query
Se usi yarn o pnpm:
yarn add @tanstack/react-query
# oppure
pnpm add @tanstack/react-query
Peer Dependencies
TanStack Query richiede React 18+. Assicurati di avere le versioni corrette:
{
"dependencies": {
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0",
"@tanstack/react-query": "^5.0.0"
}
}
Setup Base con QueryClientProvider
Il primo passo dopo l’installazione e’ avvolgere la tua app nel QueryClientProvider:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<MyApplication />
</QueryClientProvider>
)
}
export default App
Configurazione delle Default Options
Puoi personalizzare il comportamento globale di tutte le query e mutation:
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minuti - i dati restano "freschi"
gcTime: 1000 * 60 * 10, // 10 minuti - tempo in cache dopo inattivita'
retry: 3, // numero di tentativi in caso di errore
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
refetchOnWindowFocus: true, // rifetch quando la finestra torna in focus
refetchOnReconnect: true, // rifetch al ripristino della connessione
},
mutations: {
retry: 1, // un solo retry per le mutations
},
},
})
staleTime e gcTime
Queste due opzioni sono fondamentali:
- staleTime: Per quanto tempo i dati sono considerati freschi. Default
0(subito stale). - gcTime: Per quanto tempo i dati inattivi rimangono in memoria. Default
5 minuti.
// Esempio: dati che cambiano raramente
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: Infinity, // non diventano mai stale automaticamente
},
},
})
Supporto TypeScript
TanStack Query ha un eccellente supporto TypeScript integrato. I tipi vengono inferiti automaticamente dalla queryFn:
import { useQuery } from '@tanstack/react-query'
interface Todo {
id: number
title: string
completed: boolean
}
function useTodos() {
return useQuery<Todo[]>({
queryKey: ['todos'],
queryFn: async (): Promise<Todo[]> => {
const res = await fetch('/api/todos')
if (!res.ok) throw new Error('Errore nel fetch')
return res.json()
},
})
}
Puoi anche definire il tipo di errore:
import { useQuery } from '@tanstack/react-query'
interface ApiError {
message: string
code: number
}
const { data, error } = useQuery<Todo[], ApiError>({
queryKey: ['todos'],
queryFn: fetchTodos,
})
// error e' tipizzato come ApiError | null
if (error) {
console.log(error.code) // TypeScript conosce il tipo
}
Setup Completo per un Progetto
Ecco un esempio completo con tutte le configurazioni raccomandate:
// lib/query-client.ts
import { QueryClient } from '@tanstack/react-query'
export function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60, // 1 minuto
gcTime: 1000 * 60 * 5, // 5 minuti
retry: 2,
refetchOnWindowFocus: false, // disabilita per sviluppo
},
},
})
}
// main.tsx
import { QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { makeQueryClient } from './lib/query-client'
const queryClient = makeQueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<Router />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
)
}