Melhores Práticas da Camada de Dados
Um resumo condensado das 25 melhores práticas mais importantes extraídas de todas as páginas desta seção.
Busque em todas as páginas da documentação
Um resumo condensado das 25 melhores práticas mais importantes extraídas de todas as páginas desta seção.
Assuma que a rede é não confiável: Projete leituras do cache local primeiro e escritas como reconciliação assíncrona - não como portões de fetch bloqueadores em cada tela.
Publique um contrato de UX: Os usuários devem sempre saber se os dados estão ativos, desatualizados, sincronizando ou indisponíveis - concorde com o design antes da implementação.
Use NetInfo para conectividade - não sondas de fetch: @react-native-community/netinfo reflete a alcançabilidade contínua; um ping HTTP único ao montar mente em portais cativos.
Oculte o banner offline durante a alcançabilidade desconhecida: isInternetReachable === null na inicialização a frio não é offline - espere um false definitivo antes de alertar.
Conecte onlineManager ao NetInfo na inicialização: TanStack Query deve pausar as retentativas offline - retentativas ilimitadas no modo avião drenam a bateria e sobrecarregam os logs.
Conecte focusManager ao AppState: As políticas de refetch devem respeitar o primeiro plano/segundo plano do celular - não as suposições de window.focus do desktop.
Stale-while-revalidate por padrão: Exiba dados de Query cacheados com um rótulo dataUpdatedAt - spinners de tela cheia apenas quando isPending && !data.
Diferencie erros offline de erros do servidor: Manchetes, caminhos de retentativa e análises diferentes - um 500 com dados cacheados não é o mesmo que modo avião.
Aceite escritas locais offline: Enfileire mutações com idempotencyKey - os usuários não devem perder envios de formulário em um túnel.
Escolha o armazenamento pela forma dos dados: AsyncStorage para JSON pequeno; SQLite para linhas relacionais; MMKV para leituras síncronas de caminho crítico - não uma loja para tudo.
Versionar todos os esquemas persistidos: app:storage:meta:v1 para AsyncStorage, PRAGMA user_version para SQLite, meta:schemaVersion para MMKV - envie migrações antes que novas formas cheguem à produção.
Execute migrações antes da primeira renderização da tela: Portão de inicialização em _layout raiz - as telas nunca devem ler chaves ou tabelas não migradas.
Recupere-se de corrupção sem white-screening: safeParse + redefinição de chave com escopo - isole a outbox antes de clear() em aplicativos de campo.
Nomeie chaves de armazenamento por domínio: sync:outbox:v1, user:preferences:v1 - evita exclusões acidentais entre recursos e facilita o escopo de logout.
Habilite WAL e chaves estrangeiras do SQLite na criação: PRAGMA journal_mode = WAL e foreign_keys = ON em cada novo banco de dados - desempenho e integridade referencial desde o primeiro dia.
Use prepared statements ou templates db.sql: Nunca concatene a entrada do usuário em execAsync - injeção de SQL também se aplica no dispositivo.
Use withExclusiveTransactionAsync para pacotes de escrita múltipla: O withTransactionAsync padrão pode intercalar consultas concorrentes - escopo exclusivo para inspeção salva.
Adicione synced, updated_at e marcadores de exclusão a tabelas de sincronização: Exclusões devem replicar - sinalizadores de exclusão lógica superam a remoção completa para sincronização offline.
Padrão para reconciliação com autoridade do servidor: Dinheiro, inventário e dados de conformidade não devem usar o último a escrever vence de forma ingênua - documente edições descartadas na UX.
Combine LWW com timestamps do servidor: Apenas Date.now() do cliente perde edições offline concorrentes - substitua updated_at pelo valor do servidor em cada confirmação.
Implemente UI otimista com rollback: TanStack Query onMutate captura o cache anterior; onError o restaura - sinalizadores pending por linha superam spinners globais.
Persista mutações falhadas - UI otimista sem fila perde criações: A outbox do AsyncStorage ou SQLite repete na reconexão com a mesma chave de idempotência.
Registre a sincronização em segundo plano no escopo global: TaskManager.defineTask antes do React montar; registerTaskAsync após o login - descarregue a outbox em janelas adiáveis do SO.
Trate tarefas em segundo plano como uma rede de segurança: O flush em primeiro plano na reconexão do NetInfo é o principal - minimumInterval: 15 minutos não é entrega em tempo real.
Logout limpa todas as camadas: queryClient.clear(), chaves AsyncStorage de sessão, instância de usuário MMKV e tabelas de usuário SQLite - cache desatualizado é um defeito de segurança.
TanStack Query + NetInfo + AsyncStorage (preferências/outbox) + expo-sqlite (dados relacionais offline). Adicione MMKV quando a análise de desempenho provar que AsyncStorage está no caminho crítico. Adicione expo-background-task quando os aplicativos de campo precisarem de flush adiado.
Fila AsyncStorage para dezenas de pequenos patches JSON. SQLite quando a outbox referencia linhas relacionais, anexos ou milhares de itens pendentes - veja Padrões AsyncStorage e expo-sqlite.
Raramente para captura de campo em um único dispositivo. Adote quando a edição simultânea real por vários usuários for um requisito do produto - veja Estratégias de Sincronização.
Query é responsável pelo cache de estado do servidor e mutações otimistas. Esta seção é responsável pela durabilidade, sincronização e ciclo de vida do SO - leia cruzado ../state-management/tanstack-query/tanstack-query.md.
Versões da Stack: Esta página foi escrita para React 19.2.3, React Native 0.86.0 e Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026