Capítulo 13: Data Fetching Assíncrono e Caching com TanStack Query
Especialização Frontend com React & TypeScript • React 19, Hooks, Estado Global e Next.js
🗺️ Mapa Conceitual do Tópico
flowchart TD
QUERY["useQuery({ queryKey: ['orders'] })"] --> CHECK_CACHE{"Dados em cache e frescos (staleTime)?"}
CHECK_CACHE -- "Sim" --> RETURN_CACHE["Retorna dados instantaneamente do cache"]
CHECK_CACHE -- "Não" --> FETCH["Busca no Servidor em Background"]
FETCH --> UPDATE_CACHE["Atualiza cache e re-renderiza componentes"]
🏛️ 1. O Conceito de Estado de Servidor (Server State)
Na arquitetura de front-end moderna, distinguimos claramente dois tipos de estado:
- Client State: Dados efêmeros que existem apenas no navegador (tema dark/light, modal aberto, aba selecionada).
- Server State: Dados que residem no banco de dados remoto e pertencem ao servidor (catálogo de produtos, saldo bancário, permissões).
Tentar gerenciar Server State com useEffect + useState resulta em duplicação de código, falta de cacheamento, dados obsoletos e condições de corrida. O TanStack Query (React Query) foi projetado especificamente para gerenciar o Server State.
⚡ 2. Os Pilares: Caching, Invalidação e Mutações
useQuery: Busca declarativa com controle de cache automático através daqueryKey.staleTimevsgcTime:staleTime: Período durante o qual os dados em cache são considerados “frescos” e nenhuma nova requisição é disparada.gcTime(Garbage Collection Time): Tempo que os dados inativos permanecem na memória RAM antes de serem desalocados.
useMutation: Execução de operações de escrita (POST,PUT,DELETE) com invalidação de cache associada (queryClient.invalidateQueries()).
📊 3. Comparativo: useEffect + fetch vs TanStack Query
| Recurso de Rede | useEffect Manual |
TanStack Query v5 |
|---|---|---|
| Cache em Memória | ❌ Inexistente | ✅ Automático por queryKey |
| Deduplicação de Requisições | ❌ Dispara múltiplas buscas idênticas | ✅ Consolida chamadas simultâneas |
| Atualização em Janela em Foco | ❌ Não suportado | ✅ Refetch automático inteligente |
| Tratamento de Loading/Error | Verboso e manual | ✅ Flags nativas isPending, isError |
⚠️ 4. Armadilhas Comuns e Anti-Padrões de Produção
- Query Keys Dinâmicas Mal Formadas: Usar strings simples em vez de arrays hierárquicos impede a invalidação granular. Use
['users', userId]em vez de'users-' + userId. - Esquecer de Retornar a Promise no
queryFn: Funções passadas paraqueryFndevem obrigatoriamente retornar uma Promise resolvida com os dados reais ou lançar uma exceção em caso de erro HTTP.
💡 5. Diretrizes de Engenharia (Meta & React Docs)
- Configure
staleTimeConsciente: O padrão do TanStack Query éstaleTime: 0. Para dados corporativos que mudam raramente, definastaleTime: 1000 * 60 * 5(5 minutos) para economizar processamento no backend. - Adote Mutações Otimistas (Optimistic Updates): Em interfaces interativas como curtidas ou marcação de tarefas, atualize o cache visual antes mesmo do retorno da API com rollback automático em caso de erro.
💻 6. Demonstração Arquitetural do Conceito
// queryFactory.ts - Definição centralizada de queries
import { useQuery } from "@tanstack/react-query";
export function useSystemHealth() {
return useQuery({
queryKey: ["system", "health"],
queryFn: async () => {
const res = await fetch("/api/health");
if (!res.ok) throw new Error("Serviço indisponível");
return res.json() as Promise<{ status: string; uptime: number }>;
},
staleTime: 30000
});
}
📋 7. Cheat-Sheet dos Estados do useQuery
isPending: Primeiro carregamento em andamento sem dados prévios em cache.isFetching: Qualquer busca em andamento (inclusive revalidações em background).isError: Falha na requisição (erro exposto na propriedadeerror).isSuccess: Dados carregados e disponíveis emdata.
🔍 8. Diagnóstico de Performance & React DevTools Profiler
Utilize a ferramenta oficial TanStack Query Devtools:
- Status das Queries em Tempo Real: Monitore os estados
fresh,fetching,staleeinactive. - Invalidação Manual: Clique em Invalidate para testar se os componentes na tela refletem as novas informações da API sem recarregar a página.
🧪 9. Casos de Teste e Cenários de Borda Recomendados
- 🔍 Simulação de Erro 500: Teste o comportamento da UI quando a API retorna erro de servidor e confirme os retries automáticos.
- 🔍 Retorno Offline: Simule a perda de conexão com a internet e valide o aviso de dados em cache desatualizados.
- 🔍 Mutação com Rollback: Simule uma falha na mutação e comprove que o estado otimista reverte para o valor original.