Primeiros Estados - Primeiros Estados e civilizações do mundo - StudHistória
Primeiros Estados e civilizações do mundo - StudHistória

Como lidar com primeiros estados em máquinas de estado

Achei que era algo simples no começo. Você cria um objeto com os valores iniciais, conecta o reducer e segue a vida. Quase todo mundo faz isso. O problema é que o primeiro estado nunca é tão inocente quanto parece, especialmente quando a aplicação cresce e você precisa lidar com serialização, hidratação do servidor e cenários de recuperação após falhas. No meu caso, trabalhei num projeto de e-commerce onde o carrinho de compras precisava persistir entre sessões. O primeiro estado era definido num arquivo separado, importado pelo módulo principal. Parecia limpo. Dois meses depois, começamos a ver bugs estranhos: o carrinho às vezes vinha vazio, às vezes vinha com itens duplicados, e às vezes trazia dados de outro usuário. Descobri que o problema não estava no reducer, estava na forma como estávamos tratando o primeiro estado durante a hidratação do lado do cliente.

O que são primeiros estados na prática

Primeiros estados, ou initial states em inglês, são simplesmente os valores que seu estado assume quando nada aconteceu ainda. Nenhuma ação foi despachada, nenhum efeito colateral disparou, o componente acabou de montar. É o ponto de partida. A maioria dos tutoriais mostra um exemplo com um contador ou uma lista de tarefas. Funciona. Mas na vida real, os primeiros estados quase nunca são só objetos literais. Você precisa considerar tipos, estruturas aninhadas, e o fato de que o JavaScript vai tentar convencer você de que null é diferente de undefined quando na verdade você deveria tratar os dois da mesma forma na maior parte dos casos. O padrão mais comum que vejo é alguém definindo o estado inicial como um array vazio ou um objeto vazio, sem pensar que eventualmente você vai precisar recuperar esse estado do localStorage ou de uma API. Um array vazio é fácil de lidar. Um objeto vazio? Só até você tentar acessar uma propriedade que não existe e começar a ver undefined quebrando things em cascata.

Problemas que ninguém conta

A primeira armadilha é a crença de que o primeiro estado é imutável. Ele não é. Pelo menos não no sentido que você pensa. Se você define o estado inicial como um objeto literal e depois modifica esse objeto em algum lugar sem fazer clone, todas as suas instâncias vão compartilhar a mesma referência. Isso é particularmente traiçoeiro em aplicações React, onde o estado inicial pode ser compartilhado entre renders de componentes que nunca deveriam ter estado em comum. Outro problema que aprendi na marra: o primeiro estado que você escreve no código quase nunca é o primeiro estado que aparece no navegador. Tem o estado serializado pelo servidor, tem o estado que volta do cache, tem o estado que vem de cookies ou de parâmetros de URL. Cada uma dessas fontes tem seu próprio formato, sua própria maneira de falhar, e você precisa decidir se trata cada uma delas separadamente ou se normaliza tudo num único ponto. A maioria das pessoas não normaliza. Isso funciona até funcionar mal.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Te conto um caso específico que me custou umas seis horas numa sexta à tarde. Estávamos usando Zustand pra gerenciar o estado global de uma plataforma de análises. O primeiro estado tinha um campo que era um mapa de datas pra valores numéricos. Na teoria, era um SimpleMap. Na prática, quando o estado voltava doIndexedDB, o mapa virava um array de tuplas porque o serializer não entendia Map. O reducer não fazia fallback. A interface simplesmente quebrava sem erro visível. A solução foi criar uma função de normalization que detectava o tipo e convertia de volta pro formato esperado. Levou uns vinte minutos pra escrever, mas as seis horas que eu perdi foram só pra diagnosticar que o problema não era no reducer, era na entrada.

Uma alternativa que vale a pena considerar

Se você tá começando um projeto novo e não quer se preocupar com esses detalhes logo de cara, existem bibliotecas como Zustand, Jotai ou mesmo o useReducer nativo do React que resolvem parte do problema. Mas a verdadeira solução não é a biblioteca, é o padrão que você adota. Definir os primeiros estados como funções que retornam cópias fresh, nunca objetos mutáveis, e tratar a hidratação como uma etapa explícita do ciclo de vida, não como um detalhe secundário. Também existe o caso dos primeiros estados que vêm do backend. Aqui a dica é simples mas difícil de seguir: nunca confie no formato que o backend te envia. Sempre valide. Sempre tenha um fallback. E sempre trate o primeiro estado como algo que pode estar incompleto, corrompido ou vazio. A melhor defesa contra bugs de primeiro estado é não assumir que o primeiro estado vai ser bom.

Se quiser ver como isso funciona no código, dá uma olhada na documentação do Zustand ou nos exemplos do Redux Toolkit. Ambos têm seções sobre initial state que são bem mais honestas do que a maioria dos tutoriais por aí. E se você já passou por um problema assim, compartilhe nos comentários. Às vezes o pior bug de primeiro estado é aquele que você já resolveu e esqueceu que existia.