Quando o formulario de um app corporativo deixa de ser curto e vira fluxo com varias etapas, anexo, validacao, pausa e retorno depois, o problema muda de escala. Ja nao basta saber validar um campo e enviar para a API. O app passa a precisar responder perguntas mais chatas e mais reais: o que acontece se a pessoa fechar o app no meio? se receber uma ligacao? se cair a rede? se voltar por deep link? se a tela quebrar ao restaurar um estado antigo? se o rascunho salvo nao combinar mais com a versao nova do fluxo?
Essas perguntas aparecem cedo em vistoria, checklist, cadastro operacional, diagnostico, visita tecnica, onboarding assistido e qualquer formulario mais longo no celular. E quase sempre aparecem antes de a equipe estar pronta para responder.
Este guia organiza uma abordagem pratica para formularios multi-etapa no React Native, conectando formulario, rascunho local, restauracao de navegacao e retomada segura do fluxo.
1. Multi-etapa nao e so dividir tela em blocos
Fluxo multi-etapa parece, na superficie, apenas um wizard com botao proximo e voltar. Mas em app corporativo ele carrega muito mais: progresso parcial, dependencia entre campos, etapas opcionais, dados vindos da API, erro remoto, pausa longa e retomada em contexto diferente. Se o fluxo nao for pensado como estado persistivel, a tela ate funciona no demo, mas falha no uso real.
Por isso, a primeira separacao importante e esta:
- estado de formulario em edicao;
- estado de navegacao entre etapas;
- rascunho local persistido;
- payload final que sera enviado.
Tratar essas quatro coisas como se fossem uma so costuma criar retrabalho e restauracao confusa.
2. O artigo de formulario continua valendo, mas agora com ciclo maior
O artigo formularios no app com React Hook Form e Zod ja deixou clara a fronteira entre schema, submit, erro local e erro de API. Aqui, a diferenca e o ciclo de vida. O formulario deixa de existir apenas enquanto a screen esta aberta. Ele pode precisar sobreviver a pausa, reinicio e troca de rota.
Isso nao muda a necessidade de uma fonte de verdade unica para valores e validacao. So acrescenta uma responsabilidade nova: decidir quando gravar, restaurar, invalidar e descartar esse estado.
3. Persistir navegacao e persistir rascunho nao sao a mesma coisa
A documentacao oficial de state persistence do React Navigation explica um caso bem claro: salvar a localizacao da pessoa no app para que ela volte ao mesmo ponto depois de reiniciar. O recurso usa onStateChange para salvar o estado de navegacao e initialState para restaurar esse estado depois.
Isso e util, mas nao resolve sozinho o formulario. Voltar para a mesma etapa nao significa recuperar os dados digitados. Da mesma forma, recuperar um rascunho sem recuperar a etapa certa pode jogar a pessoa em uma tela desalinhada com o que ela ja preencheu.
O melhor desenho costuma separar:
- estado de navegacao, quando faz sentido restaurar a rota;
- estado de rascunho do formulario, salvo com chave propria;
- regras para reconciliar um com o outro na retomada.
4. React Navigation mostra como restaurar rota, mas com cautela
O exemplo oficial do React Navigation usa AsyncStorage.getItem para restaurar o estado salvo, passa o resultado em initialState e volta a salvar em toda mudanca de navegacao com onStateChange. A propria documentacao tambem mostra um cuidado importante: se houver um deep link inicial, o exemplo evita restaurar o estado salvo e deixa o link ter precedencia.
Esse detalhe importa muito para fluxo multi-etapa. Se o app reabre por um link operacional, notificacao ou acao externa, restaurar cegamente uma navegacao antiga pode mandar a pessoa para o lugar errado. Em producao, retomada boa nao e a que restaura sempre. E a que restaura quando o contexto ainda faz sentido.
5. AsyncStorage ajuda no rascunho simples, mas nao e cofre
O repositorio oficial do AsyncStorage o descreve como armazenamento assincrono, persistente, sem criptografia, baseado em chave-valor e compativel com a ideia da Web Storage API, com extensoes para operacoes em lote. Isso o torna muito util para rascunho simples, filtros, preferencia e pequenos estados do app.
Ao mesmo tempo, a mesma descricao ja deixa o limite claro: ele e unencrypted. Ou seja, nao e a camada certa para guardar segredo sensivel so porque o fluxo ficou mais longo. Token, senha, chave e credencial seguem pedindo armazenamento proprio, como discutido em persistencia local com AsyncStorage, SecureStore e SQLite.
Para rascunho multi-etapa, AsyncStorage funciona bem quando:
- o payload ainda e relativamente pequeno;
- o dado nao e segredo critico;
- o app so precisa salvar e restaurar de forma simples;
- nao ha consulta complexa por varios registros.
6. Rascunho longo pede checkpoint, nao so save final
Esperar a pessoa tocar em salvar rascunho ao fim de tudo costuma ser tarde demais. Em mobile, interrupcao acontece o tempo todo. Por isso, formularios multi-etapa costumam funcionar melhor com checkpoints claros: ao concluir etapa, ao mudar de secao, ao voltar da tela ou ao detectar ida para background.
Isso nao significa gravar tudo a cada tecla sem criterio. Significa escolher momentos consistentes de persistencia. Em varios casos, salvar no fim de cada etapa e suficiente. Em outros, vale combinar etapa concluida com debounce em campos mais longos e com persistencia ao sair do app.
7. AppState entra para proteger a retomada
A documentacao oficial do React Native define AppState como a API que informa se o app esta ativo, em background ou inativo. Ela tambem mostra o evento change para observar essas transicoes.
Para formulario multi-etapa, isso abre uma possibilidade muito util: gravar checkpoint quando o app sai de active para background. Nao resolve todos os cenarios, mas reduz bastante a chance de perder progresso por interrupcao normal do celular.
Esse uso se soma ao que ja vimos em autenticacao, biometria e cache. AppState nao serve so para bloquear tela sensivel ou refetchar dado stale. Ele tambem ajuda a tornar o formulario menos fragil diante do mundo real.
8. Estado persistido precisa ser serializavel
O React Navigation faz um alerta direto na secao de warning: cada rota, parametro e estado de navegacao precisa ser totalmente serializavel para a persistencia funcionar direito. A documentacao cita explicitamente que nao deve haver funcoes, instancias de classe nem estruturas recursivas nos params que serao salvos.
Esse aviso conversa diretamente com rascunho de formulario. Se a equipe tentar persistir tudo sem filtro, logo aparecem objetos que nao deviam ir para armazenamento: callback, File, instancia complexa, referencia circular ou blob improvisado de UI. Resultado: restauracao quebrada, parse ruim ou app preso em estado invalido.
O desenho maduro salva apenas o que precisa ser restaurado e em formato previsivel.
9. Carregamento inicial da retomada precisa existir
A mesma documentacao do React Navigation lembra que a restauracao e assincrona e, por isso, o app precisa renderizar uma view vazia ou de loading por um momento antes de decidir o estado inicial. Esse detalhe parece pequeno, mas evita transicoes estranhas: a pessoa ve a etapa 1 por um instante, depois salta para a etapa 4, ou o form carrega vazio e so depois recebe rascunho.
Em fluxo multi-etapa, a tela de retomada deve deixar claro que esta restaurando contexto. Isso vale tanto para navegacao quanto para rascunho. A pior experiencia aqui nao e esperar 300 milissegundos. E ver o app mudar de ideia no meio da renderizacao.
10. Deep link, versao nova e erro de tela precisam ter saida
O exemplo oficial do React Navigation tambem recomenda uso de error boundary e, se ocorrer erro, limpar o estado persistido para evitar que o app fique preso em uma tela quebrada ao reiniciar. A mesma pagina tambem deixa claro que o recurso e especialmente util em desenvolvimento, mas em producao pede cautela exatamente por esse risco.
Essa observacao vale ouro para rascunho multi-etapa. Persistir e bom. Persistir lixo e persistir tela quebrada nao e. Por isso, convem definir algumas saidas claras:
- nao restaurar navegacao antiga se houver deep link relevante;
- versionar a chave do rascunho quando a estrutura do formulario mudar muito;
- limpar estado antigo se a restauracao falhar ou o schema nao bater;
- oferecer recomeco seguro em vez de loop de erro.
11. Multi-etapa bom sabe quando limpar o rascunho
Outro erro comum e acertar o save e errar o descarte. Rascunho nao deveria sobreviver indefinidamente depois do envio real. Depois de um submit confirmado, a regra mais comum e limpar o rascunho correspondente, invalidar o que precisa no cache e redirecionar a pessoa com seguranca.
Em alguns cenarios, ainda vale guardar um recibo minimo ou identificador da operacao concluida. Mas manter o rascunho inteiro depois do sucesso costuma gerar reabertura enganosa, duplicidade ou confusao de suporte.
12. Quando AsyncStorage deixa de bastar
Se o fluxo passa a guardar muitos rascunhos, anexos relacionados, status detalhado, sincronizacao posterior ou consulta por varios registros, o artigo de persistencia local continua sendo a melhor fronteira tecnica. Nesse ponto, SQLite tende a respirar melhor do que um conjunto grande de chaves soltas ou um JSON crescente em AsyncStorage.
O critico aqui nao e ser purista com a ferramenta. E reconhecer a hora em que o rascunho deixou de ser simples preferencia local e virou dado operacional do app.
13. Um desenho simples que costuma funcionar bem
- Manter uma fonte de verdade unica para os valores do formulario.
- Persistir rascunho em checkpoints, nao apenas no fim.
- Usar
AsyncStoragepara rascunho simples e nao sensivel. - Usar
AppStatepara salvar ao ir para background quando fizer sentido. - Persistir navegacao separadamente do payload do formulario.
- Restaurar com loading inicial e criterio para deep link.
- Salvar apenas estado serializavel.
- Versionar e limpar rascunho quando o fluxo mudar ou concluir.
14. Quando vale um diagnostico tecnico
Se hoje o app perde formulario no meio, reabre em etapa errada, restaura dado quebrado, acumula rascunho antigo ou nao sabe separar navegacao, payload e persistencia local, talvez o problema nao esteja na tela isolada. Falta arquitetura de retomada. Nessa hora, um diagnostico tecnico ajuda a redesenhar checkpoints, chaves de armazenamento, validacao de retomada e descarte seguro antes que o fluxo multi-etapa vire um passivo fixo do produto.
Formulario longo no mobile so vira ativo quando o app respeita a interrupcao, a retomada e o contexto real de quem esta usando. O resto e demo bonito.
Referencias editoriais: React Hook Form, React Navigation - State persistence, React Native Async Storage 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.