Um dos sinais mais claros de que um app corporativo esta crescendo sem disciplina e quando cada tela passa a reinventar o proprio consumo de API. Uma tela usa useEffect com fetch, outra dispara refetch no pull-to-refresh, outra guarda resposta em estado local, outra tenta sincronizar erro na mao, e logo o time ja nao sabe mais por que certas listas atualizam demais, outras ficam velhas, algumas piscam ao voltar para a tela e mutacoes so refletem no app depois de sair e entrar de novo.
TanStack Query, conhecido por muita gente pelo nome antigo React Query, ajuda justamente a organizar esse bloco de responsabilidades. Ele nao substitui sua API, nem vira banco local, nem resolve sozinho o offline complexo. O que ele faz muito bem e gerenciar server state: leitura, cache, refetch, invalidacao, mutacoes e reacoes previsiveis a foco e reconexao. Para app React Native corporativo, isso costuma reduzir bastante o ruido operacional do frontend mobile.
Este guia organiza um uso pratico de TanStack Query no React Native, com foco em app que conversa com API real, tem login, tela de lista, detalhe, mutacao, rede instavel e necessidade de nao espalhar loading, retry e refetch por todo lado.
1. O problema que TanStack Query resolve nao e estado de tela
A propria documentacao da TanStack posiciona a biblioteca como camada para dados assincronos e cache de servidor. Isso e importante porque muitas equipes tentam usa-la para tudo. Valor de input, modal aberto, aba ativa, ordenacao local ou item selecionado continuam sendo estado de tela. TanStack Query entra quando o dado vem do backend, pode ficar em cache, pode ficar stale, pode precisar invalidar e pode sofrer mutacao.
Em app corporativo, isso costuma aparecer em listas de tarefas, pedidos, chamados, visitas, agenda e detalhes de entidade. O objetivo nao e apenas buscar JSON. E saber quando reaproveitar, quando refazer, quando marcar stale e quando refletir uma mutacao sem reescrever a tela inteira.
2. Se toda query fica stale por padrao, o app precisa escolher melhor
O guia de Important Defaults da TanStack deixa um ponto bem claro: por padrao, toda query em cache e considerada stale. Isso surpreende muita gente nova na biblioteca, porque a sensacao e de que o cache nao esta funcionando. Na verdade, o cache existe, mas a biblioteca assume uma postura agressiva de atualizacao.
A mesma documentacao explica que queries stale podem ser refetchadas automaticamente quando uma nova instancia monta, quando a janela volta ao foco e quando a rede reconecta. Em app corporativo, isso e otimo quando faz sentido e ruim quando fica sem criterio. Por isso, staleTime vira uma das configuracoes mais importantes do projeto.
Em vez de deixar tudo no padrao, vale pensar em familias de dado:
- dados que mudam muito e pedem staleTime curto;
- dados de referencia que podem ficar minutos frescos;
- dados quase estaticos que podem usar
Infinitye depender de invalidacao manual.
Esse desenho reduz refetch exagerado sem cair no outro extremo de tela sempre velha.
3. Query key mal desenhada vira cache confuso
Na pratica, a identidade do cache depende da query key. Se a lista geral, a lista filtrada e o detalhe do item nao se diferenciam direito, a invalidacao vira loteria. Em app corporativo, um padrao simples costuma funcionar melhor: uma chave base por recurso e subchaves por contexto relevante, como filtro, pagina, conta, unidade ou identificador.
Um jeito util de pensar:
["visitas"]para listagem geral;["visitas", "filtro", status]para lista filtrada;["visita", visitaId]para detalhe.
Quando a query key reflete o contrato do backend e o recorte da tela, invalidar fica muito mais previsivel.
4. Cache nao e banco local, e staleTime nao e permanencia eterna
Outro default importante: queries sem observadores ativos ficam inativas e, por padrao, sao coletadas do cache depois de 5 minutos. A documentacao chama esse tempo de gcTime. Isso ajuda a conter memoria, mas tambem deixa claro um limite importante: cache de query nao e o mesmo que persistencia local estruturada.
Se o app precisa reabrir com dado util mesmo depois de muito tempo, ou segurar rascunho, fila ou entidade editavel offline, o artigo persistencia local com AsyncStorage, SecureStore e SQLite continua sendo parte da resposta. TanStack Query resolve muito bem cache de servidor em uso recente. Ele nao substitui banco local de negocio.
5. React Native nao tem window focus, entao o app precisa ensinar isso
A pagina oficial de React Native da TanStack Query explica um detalhe essencial: em web, a biblioteca ja sabe refetchar quando a janela volta ao foco. Em React Native, quem fornece essa informacao e o AppState. O exemplo oficial usa focusManager junto da API AppState do React Native para marcar o app como focado quando o estado volta para active.
Isso conversa diretamente com a documentacao do React Native, que define AppState como a API capaz de informar se o app esta ativo, em background ou inativo. Para app corporativo, essa ligacao e muito valiosa porque evita gambiarra de refetch em retorno do background. A tela pode se atualizar no momento certo sem cada componente reinventar esse gatilho.
Tambem vale reforcar o termo AppState como linguagem comum do time: voltar do background e um evento operacional, nao apenas visual.
6. Tela focada nao precisa manter query viva sem necessidade
A mesma pagina de React Native da TanStack tambem mostra dois ajustes muito uteis. O primeiro e um hook para refetchar queries stale quando uma screen volta ao foco usando useFocusEffect e queryClient.refetchQueries. O segundo e o uso da prop subscribed em useQuery combinada com useIsFocused, para que a tela fora de foco deixe de ficar ouvindo atualizacoes.
Isso e um detalhe pequeno com efeito grande. Em app com varias tabs, stacks profundas ou fluxos longos, manter todas as telas vivas e escutando muda custo de render e pode gerar refetch onde o usuario nem esta olhando. Em vez de tratar tudo como live o tempo inteiro, o app pode escolher melhor.
7. Rede instavel tambem precisa entrar na conta do cache
O guia de React Native da TanStack Query tambem mostra como integrar conectividade real do aparelho via onlineManager, usando NetInfo ou expo-network. Isso faz diferenca em app corporativo porque rede movel ruim nao e excecao. E rotina.
Quando o app informa corretamente se esta online ou offline, a biblioteca pode refetchar na reconexao com mais previsibilidade. Sem isso, varios comportamentos parecem aleatorios: a pessoa volta sinal, mas a lista nao atualiza; ou a tela tenta refetchar em momento em que ainda nao existe conectividade real.
Esse ponto se conecta com offline, fila e sincronizacao com API. TanStack Query ajuda com leitura e reconexao. Fila de escrita offline, conflito e reenvio idempotente continuam pedindo desenho proprio.
8. Mutation boa quase sempre termina em invalidacao clara
O guia de invalidations from mutations resume bem a ideia: quando uma mutacao acontece com sucesso, e bem provavel que queries relacionadas precisem ser invalidadas e talvez refetchadas. O exemplo oficial usa onSuccess com queryClient.invalidateQueries para invalidar uma ou varias chaves relacionadas. A documentacao ainda observa que, se onSuccess retornar uma Promise, a mutacao so termina de fato depois que essa etapa acabar.
Isso ajuda muito em app corporativo porque elimina parte da duplicacao manual do tipo "salvei no backend, agora atualiza a lista, o detalhe, o contador e o badge". Em vez de distribuir side effects pela tela, a regra de atualizacao fica perto da mutacao.
Um principio simples costuma funcionar bem:
- mutacao de detalhe invalida detalhe e lista relacionadas;
- mutacao de criacao invalida a lista certa;
- mutacao de exclusao invalida lista, resumo e contadores afetados.
Sem esse mapa, o app parece inconsistente mesmo quando a API respondeu corretamente.
9. Nem toda tela precisa de optimistic update
Optimistic update e poderosa, mas custa disciplina. A documentacao mostra tanto a abordagem simples baseada em UI quanto o uso de callbacks como onMutate. Ela tambem lembra um detalhe muito util: se a mutacao falhar, as variables continuam acessiveis e podem alimentar um botao de retry ou uma representacao temporaria do item com erro.
Na pratica, optimistic update funciona melhor quando:
- o efeito esperado e simples e reversivel;
- o usuario se beneficia muito da resposta imediata;
- o rollback e claro caso a API rejeite.
Em app corporativo, isso combina mais com marcar favorito, trocar status leve ou inserir item visual temporario do que com fluxo financeiro, aprovacao critica ou operacao que dependa de validacao forte do backend. Nesses casos, feedback de carregamento e invalidacao clara costumam ser mais seguros do que fingir sucesso cedo demais.
10. Retry padrao de query e diferente de retry de mutation
Outro ponto que costuma passar batido: o guia de defaults explica que queries falhas sao tentadas novamente 3 vezes por padrao, com backoff exponencial. Ja o guia de mutations diz que mutacoes nao sao retentadas por padrao, embora isso possa ser configurado. O mesmo texto tambem destaca que, se a falha ocorreu porque o dispositivo estava offline, mutacoes podem ser reexecutadas na mesma ordem quando a conexao voltar.
Essa diferenca e importante porque leitura e escrita nao merecem o mesmo tratamento. Falhou buscar uma lista? Retry automatico costuma ser razoavel. Falhou aprovar um pedido? Ja exige mais cuidado, porque retentar sem criterio pode gerar experiencia ruim ou ate duplicidade quando a API nao foi desenhada com idempotencia.
Essa camada conversa diretamente com validacao e erros de API REST e com o termo idempotencia.
11. TanStack Query ajuda muito, mas nao substitui fila local
Em app corporativo com uso offline real, a tentacao comum e empurrar tudo para o cache da biblioteca e esperar que isso resolva escrita pendente. Nao resolve. Cache de leitura, mutacao com retry e reconnect ajudam bastante, mas fila local de negocio continua sendo outro problema. Quando a pessoa cria evidencia sem sinal, edita campos em sequencia ou precisa enviar lote depois, o app ainda precisa de uma estrutura propria para armazenar, ordenar e reconciliar essas acoes.
Em outras palavras: TanStack Query e excelente para server state online-first com boa degradacao. Quando o fluxo vira offline-first de verdade, ele deve conversar com persistencia local e fila dedicada em vez de tentar virar tudo sozinho.
12. Um desenho simples que costuma funcionar bem
- Use TanStack Query para toda leitura de API recorrente.
- Defina query keys que representem recurso e contexto de tela.
- Ajuste
staleTimepor tipo de dado em vez de aceitar o padrao para tudo. - Ligue
focusManageraoAppStateeonlineManagera conectividade real. - Invalide queries relevantes no
onSuccessdas mutacoes. - Use optimistic update so onde rollback e simples e honesto.
- Separe cache de leitura de persistencia e fila local de negocio.
13. Quando vale um diagnostico tecnico
Se hoje o app sofre com lista que nao atualiza, loading espalhado, refetch imprevisivel, mutacao que nao reflete na UI e comportamento diferente entre background, reconexao e foco de tela, o problema nao esta apenas em um hook. Falta uma estrategia de server state. Nessa hora, um diagnostico tecnico ajuda a organizar query keys, contrato de API, offline, retries e pontos de invalidacao sem transformar o app em uma colcha de remendos.
O melhor uso de TanStack Query nao e colocar mais uma biblioteca no projeto. E criar uma linguagem comum para cache, foco, rede e mutacao no app inteiro.
Referencias editoriais: TanStack Query - React Native, TanStack Query - Important Defaults, TanStack Query - Query Invalidation, TanStack Query - Invalidations from Mutations, TanStack Query - Mutations, TanStack Query - Optimistic Updates e React Native - AppState.
Termos tecnicos desta leitura
Alguns conceitos aparecem com frequencia neste tema. Abrir o glossario ajuda a comparar definicoes, exemplos e leituras relacionadas sem sair do contexto do artigo.