Utilizando TanStack Query no React
Gerenciar requisições HTTP, cache e estados de carregamento pode rapidamente se tornar algo repetitivo em aplicações React. O TanStack Query surgiu para simplificar esse processo, oferecendo cache automático, sincronização de dados e uma experiência muito mais agradável para trabalhar com APIs.
O que é TanStack Query?
TanStack Query é uma biblioteca responsável por gerenciar o estado assíncrono da aplicação.
Ela ajuda a lidar com:
- Requisições HTTP;
- Cache de dados;
- Loading e Error;
- Atualização automática de informações;
- Revalidação de dados;
- Mutations.
O principal objetivo é reduzir a quantidade de código necessário para trabalhar com APIs.
Instalando a biblioteca
Instalação utilizando npm:
npm install @tanstack/react-query
Ou utilizando yarn:
yarn add @tanstack/react-query
Configurando o Query Client
Antes de utilizar os hooks, é necessário criar o QueryClient.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<Routes />
</QueryClientProvider>
);
}
Agora toda a aplicação terá acesso ao cache do TanStack Query.
Fazendo a primeira consulta com useQuery
Imagine uma API que retorna usuários:
async function getUsers() {
const response = await fetch('/api/users');
return response.json();
}
Utilizando o useQuery:
import { useQuery } from '@tanstack/react-query';
function Users() {
const { data, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: getUsers
});
if (isLoading) {
return <p>Carregando...</p>;
}
if (error) {
return <p>Erro ao buscar usuários.</p>;
}
return (
<>
{data.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
</>
);
}
Com poucas linhas já temos:
- Loading;
- Error;
- Cache automático.
Entendendo o Query Key
O queryKey identifica os dados armazenados em cache.
Exemplo:
['users']
Com parâmetros:
['user', userId]
Ou:
['orders', status]
Isso permite que o TanStack Query saiba exatamente quais dados estão sendo armazenados.
Cache automático
Uma das maiores vantagens da biblioteca é o cache.
Imagine:
Página A
↓
Busca usuários
↓
Cache
↓
Página B
↓
Mesmos dados
O TanStack Query reutiliza os dados já carregados, evitando chamadas desnecessárias para a API.
Atualizando dados com useMutation
Para operações de criação, atualização e remoção utilizamos o useMutation.
Exemplo:
async function createUser(data) {
await fetch('/api/users', {
method: 'POST',
body: JSON.stringify(data)
});
}
Utilizando:
const mutation = useMutation({
mutationFn: createUser
});
Executando:
mutation.mutate({
name: 'Diogo'
});
Invalidando o cache
Após criar um usuário, podemos atualizar a lista:
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: createUser,
onSuccess() {
queryClient.invalidateQueries({
queryKey: ['users']
});
}
});
Assim os dados são recarregados automaticamente.
Trabalhando com Axios
Exemplo utilizando Axios:
import axios from 'axios';
async function getProducts() {
const response = await axios.get('/api/products');
return response.data;
}
const { data } = useQuery({
queryKey: ['products'],
queryFn: getProducts
});
Configurações importantes
staleTime
Define por quanto tempo os dados serão considerados válidos.
useQuery({
queryKey: ['users'],
queryFn: getUsers,
staleTime: 1000 * 60 * 5
});
Nesse caso:
5 minutos.
retry
Número de tentativas em caso de falha.
useQuery({
queryKey: ['users'],
queryFn: getUsers,
retry: 3
});
refetchOnWindowFocus
Atualiza automaticamente ao voltar para a aba.
refetchOnWindowFocus: false
Paginação
Exemplo:
useQuery({
queryKey: ['products', page],
queryFn: () => getProducts(page)
});
Cada página terá seu próprio cache.
Infinite Query
Muito útil para scroll infinito.
useInfiniteQuery({
queryKey: ['posts'],
queryFn: fetchPosts
});
Com isso é possível implementar:
- Feed;
- Timeline;
- Listas infinitas.
Organização recomendada
Uma estrutura comum é:
src
│
├── services
│ ├── userService.ts
│ ├── productService.ts
│
├── queries
│ ├── useUsers.ts
│ ├── useProducts.ts
│
└── components
Exemplo:
export function useUsers() {
return useQuery({
queryKey: ['users'],
queryFn: getUsers
});
}
Isso aumenta a reutilização.
Boas práticas
Utilize queryKeys padronizadas
Exemplo:
['users']
['user', id]
['orders', status]
Centralize chamadas da API
Evite colocar fetch diretamente nos componentes.
Utilize hooks customizados
Isso melhora a organização do projeto.
Configure staleTime
Nem toda consulta precisa ser atualizada constantemente.
Evite estado desnecessário
Muitas vezes não é necessário usar:
- useState;
- useEffect.
O TanStack Query já faz esse trabalho.
Vantagens
- Cache automático;
- Requisições mais simples;
- Menos useEffect;
- Retry automático;
- Atualização automática;
- Melhor experiência do usuário.
Quando utilizar?
TanStack Query é ideal para:
- Dashboards;
- Sistemas administrativos;
- E-commerce;
- Aplicações com muitas chamadas HTTP;
- Projetos React e Next.js.
Conclusão
TanStack Query é uma das melhores ferramentas para gerenciamento de estado assíncrono em aplicações React. Seu sistema de cache, invalidação automática e simplicidade ajudam a reduzir muito a quantidade de código e tornam a experiência de desenvolvimento mais produtiva.
Se você ainda utiliza apenas useEffect para buscar dados, vale a pena experimentar essa biblioteca.
Saiba mais
- TanStack Query Documentation
https://tanstack.com/query/latest - Query Keys
https://tanstack.com/query/latest/docs/framework/react/guides/query-keys - useQuery
https://tanstack.com/query/latest/docs/framework/react/reference/useQuery - useMutation
https://tanstack.com/query/latest/docs/framework/react/reference/useMutation - Infinite Queries
https://tanstack.com/query/latest/docs/framework/react/guides/infinite-queries - Query Devtools
https://tanstack.com/query/latest/docs/framework/react/devtools