Integrar React Query v5 (também conhecido como TanStack Query) com um projeto Vite + React-TS é uma excelente forma de otimizar o gerenciamento de dados em aplicações modernas. Com ele, você pode simplificar requisições assíncronas, cache de dados, paginação, mutações e muito mais.
Neste artigo, vamos explicar como configurar e usar as principais funcionalidades do React Query v5, incluindo useQuery
, useMutation
, paginação e estratégias de caching, tudo isso dentro de um ambiente Vite + React com TypeScript.
Configuração Inicial do Projeto
Comece criando um novo projeto com Vite usando o template React-TS:
npm create vite@latest my-app --template react-ts
cd my-app
npm install
Instale as dependências necessárias para trabalhar com React Query v5:
npm install @tanstack/react-query
O TanStack Query v5 requer React 18 ou superior, pois utiliza recursos como useSyncExternalStore
.
Agora, configure o QueryClient
no ponto de entrada da aplicação:
// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import App from './App'
const queryClient = new QueryClient()
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
)
Utilizando useQuery
para Buscar Dados
O useQuery
é a principal ferramenta do React Query para buscar e gerenciar dados do servidor.
Exemplo de uso:
// src/hooks/useUsers.ts
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
const fetchUsers = async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/users')
return res.data
}
export const useUsers = () => {
return useQuery({
queryKey: ['users'],
queryFn: fetchUsers
})
}
No componente:
// src/App.tsx
import { useUsers } from './hooks/useUsers'
function App() {
const { data, isLoading, isError } = useUsers()
if (isLoading) return <div>Carregando...</div>
if (isError) return <div>Erro ao carregar usuários</div>
return (
<ul>
{data?.map((user: any) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
export default App
Gerenciando Mutação de Dados com useMutation
Para operações que alteram dados no servidor, como criar, atualizar ou deletar, utilizamos useMutation
.
Exemplo:
// src/hooks/useCreateUser.ts
import { useMutation } from '@tanstack/react-query'
import axios from 'axios'
interface UserInput {
name: string
email: string
}
const createUser = async (user: UserInput) => {
const res = await axios.post('https://jsonplaceholder.typicode.com/users', user)
return res.data
}
export const useCreateUser = () => {
return useMutation({
mutationFn: createUser
})
}
Uso no componente:
// src/CreateUserForm.tsx
import { useState } from 'react'
import { useCreateUser } from './hooks/useCreateUser'
export default function CreateUserForm() {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const { mutate, isSuccess } = useCreateUser()
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
mutate({ name, email })
}
if (isSuccess) return <p>Usuário criado com sucesso!</p>
return (
<form onSubmit={handleSubmit}>
<input value={name} onChange={(e) => setName(e.target.value)} placeholder="Nome" />
<input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="E-mail" />
<button type="submit">Criar Usuário</button>
</form>
)
}
Implementando Paginação com React Query
Para listagens paginadas, o React Query oferece suporte robusto através do método useInfiniteQuery
. Ele permite carregar páginas de dados sob demanda.
Exemplo:
// src/hooks/usePaginatedUsers.ts
import { useInfiniteQuery } from '@tanstack/react-query'
import axios from 'axios'
const fetchUsersPage = async ({ pageParam = 1 }) => {
const res = await axios.get(`https://jsonplaceholder.typicode.com/users?_page=${pageParam}&_limit=5`)
return res.data
}
export const usePaginatedUsers = () => {
return useInfiniteQuery({
queryKey: ['paginated-users'],
queryFn: fetchUsersPage,
initialPageParam: 1,
getNextPageParam: (lastPage, allPages) => {
return allPages.length + 1
}
})
}
Componente para exibir os dados:
// src/PaginatedUsers.tsx
import { usePaginatedUsers } from './hooks/usePaginatedUsers'
export default function PaginatedUsers() {
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = usePaginatedUsers()
return (
<div>
{data?.pages.map((group, i) => (
<ul key={i}>
{group.map((user: any) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
))}
<button onClick={() => fetchNextPage()} disabled={!hasNextPage || isFetchingNextPage}>
Carregar Mais
</button>
</div>
)
}
Estratégias de Caching e Atualização Automática
React Query v5 facilita o controle de cache e atualização de dados. Você pode configurar:
- Tempo de vida do cache (
cacheTime
) - Intervalos de refetch automático (
refetchInterval
) - Revalidação baseada em eventos (
invalidateQueries
)
Exemplo:
useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
staleTime: 1000 * 60 * 5, // 5 minutos
gcTime: 1000 * 60 * 30 // 30 minutos
})
Você também pode invalidar queries manualmente após mutações:
const { mutate } = useMutation({
mutationFn: updateUser,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] })
}
})
Considerações Finais
Combinar Vite + React-TS com React Query v5 (TanStack Query) resulta em uma stack poderosa, rápida e produtiva para desenvolver aplicações front-end modernas.
As funcionalidades como useQuery
, useMutation
, paginação infinita e estratégias de caching permitem que você lide com dados de forma eficiente, sem precisar recarregar a página ou escrever código boilerplate para gerenciar estado local de requisições.
Além disso, o suporte nativo a suspense, melhorias nas devtools e atualizações otimistas tornam o React Query v5 uma das melhores escolhas para gerenciamento de estado remoto no ecossistema React.
Se você busca performance, simplicidade e manutenibilidade, adotar o TanStack Query v5 no seu projeto Vite + React-TS é uma decisão acertada.