“`html
Evite bugs, re-render e estados inconsistentes
Erros comuns em Zustand que você deve evitar
Se você já usou Zustand, provavelmente já viu “funciona, mas…”. Neste post eu destrincho os erros mais comuns
que causam re-render desnecessário, estados quebrados e código difícil de manter — com recomendações práticas.
1) Selecionar tudo no componente (e pagar o preço em performance)
Re-render excessivo
- Evite: `const state = useStore()` ou `useStore(s => s)` quando você só precisa de 1 ou 2 valores.
-
Use seletores: selecione exatamente o que o componente consome.
Assim, mudanças em partes não usadas não disparam re-render. -
Cuidado com objetos: se você retorna um objeto novo no selector, ele pode causar re-render mesmo quando os valores são iguais.
Prefira seletores por valor ou garanta estabilidade.
Regra prática: “Se o componente só renderiza por causa de um campo, selecione esse campo.”
Isso reduz re-render e deixa o comportamento mais previsível.
2) Mutar estado de forma indireta (e causar inconsistências)
Estado “estranho”
- Evite: alterar diretamente referências existentes (ex.: `state.items.push(…)` dentro de setter).
- Evite: manter arrays/objetos mutáveis “por conveniência” e depois “atualizar” sem trocar referência.
- Faça: crie novas referências ao atualizar estruturas (map/filter/spread).
Por que isso dói? Além de re-render imprevisível, você pode acabar com UI exibindo valores “antigos”
ou com lógica que depende de comparação referencial.
3) Criar setters instáveis e depender de efeitos errados
Loop / efeitos desnecessários
-
Evite: declarar funções dentro do componente que dependem de estado e depois usar no `useEffect`.
Se você consegue, mova para o store. -
Evite: usar efeitos para sincronizar estado local duplicado com estado do store.
Duplicar fontes de verdade quase sempre vira bug. - Prefira: efeitos para chamadas externas (API, subscriptions), não para “reconstruir” estado.
Sintoma comum: “um useEffect roda toda hora” porque alguma referência mudou.
Em muitos casos, isso é culpa de seleção ampla ou de uma função/objeto instável.
4) Implementar ações que fazem lógica demais dentro do componente
Manutenção difícil
-
Evite: componentes contendo dezenas de linhas para atualizar o store.
Quanto mais código de atualização no componente, maior a chance de divergência entre telas. - Faça: centralize ações no store (ex.: `addItem`, `removeItem`, `setFilter`).
-
Separe responsabilidade:
componente decide “o que” disparar; store decide “como” transformar o estado.
Resultado: menos duplicação, menos bugs e atualizações mais consistentes.
Você também facilita testes unitários das ações do store.
Exemplo prático: selecionando corretamente e atualizando de forma imutável
Re-render controlado
import { create } from "zustand";
type Item = { id: string; name: string };
type Store = {
items: Item[];
addItem: (name: string) => void;
removeItem: (id: string) => void;
};
export const useStore = create<Store>((set) => ({
items: [],
addItem: (name) => {
const id = crypto.randomUUID();
set((state) => ({
items: [
...state.items, // ✅ imutável (cria nova referência)
{ id, name }
]
}));
},
removeItem: (id) => {
set((state) => ({
items: state.items.filter(item => item.id !== id) // ✅ imutável
}));
}
}));
// --- No componente: selecione o mínimo necessário ---
/*
const items = useStore(s => s.items);
const addItem = useStore(s => s.addItem);
const removeItem = useStore(s => s.removeItem);
*/
O que observar:
separar seletores por valor reduz re-render; e atualizar com novas referências mantém o estado consistente.
Quer continuar evoluindo com Zustand (e React)?
Agora que você já sabe quais erros evitar, vale a pena aprofundar em padrões de organização de store, modelagem de estado e
integração com UI. A próxima leitura vai te ajudar a deixar seu código mais previsível e escalável.
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!