YuriDeveloper
Trends de Zustand que estão bombando
1) Modularidade por slices: do store único para combinações por domínio
O padrão que vem ganhando força é dividir o estado em slices ou stores por domínio (autenticação, UI, dados de domínio, etc.). Em Zustand isso é simples de chegar mantendo a API limpa e interoperável.
- Desacoplamento: cada slice gerencia seu conjunto de ações e estado.
- Reutilização: componentes consomem apenas o que realmente precisam, facilitando testes.
- Composição: é possível combinar stores diferentes sem criar dependências circulares.
Prática recomendada: exportar hooks dedicados como useAuthStore, useTodoStore e useUIStore, mantendo responsabilidades bem definidas.
2) Middlewares que ajudam de verdade: devtools, persist e além
Middlewares trazem visibilidade e resiliência ao estado. Em Zustand, a combinação mais comum inclui devtools para debugging, persist para rehydratar entre recargas e, quando faz sentido, imersão de updates com Immer.
- Devtools: inspeção de ações e estados durante o desenvolvimento.
- Persist: salva estado em localStorage (ou outro storage) para reidratação.
- Immer (opcional): facilita updates imutáveis sem boilerplate.
Dicas rápidas: use persist com uma chave clara por store, e combine devtools apenas durante o desenvolvimento para não atrapalhar o runtime.
3) Seletores eficientes: minimizando re-renderizações
A granularidade das atualizações é crucial. Com selectors bem definidos e o uso de subscribeWithSelector ou shallow, você evita re-renderizações desnecessárias ao componente consumidor.
- Prefira selecionar apenas o pedaço necessário: useStore(s => s.todos.filter(…))
- Utilize subscribeWithSelector para ouvir mudanças específicas dentro de uma store
- Shallow equality ajuda quando o estado retornado é um objeto/array novo a cada atualização
Exemplo de padrão de uso com selectors avançados:
// Exemplo conceitual (TypeScript)
import create from 'zustand';
import { devtools, persist, subscribeWithSelector } from 'zustand/middleware';
type Todo = { id: number; text: string; done: boolean; };
type Store = {
todos: Todo[];
addTodo: (text: string) => void;
toggleTodo: (id: number) => void;
// ...
};
export const useStore = create<Store>(
persist(
devtools(
subscribeWithSelector((set) => ({
todos: [],
addTodo: (text) => set((s) => ({
todos: [...s.todos, { id: Date.now(), text, done: false }],
})),
toggleTodo: (id) => set((s) => ({
todos: s.todos.map((t) => t.id === id ? { ...t, done: !t.done } : t)
})),
}))
),
{ name: 'zustand-todos' }
)
);
4) Organização para escalabilidade: quando usar vários stores vs um único com slices
Conforme a app cresce, a organização faz a diferença. Opte por stores por domínio para isolamento lógico e menor impacto de rehidratação. Em cenários com alto acoplamento entre features, um store único com slices bem definidas também funciona, desde que a composição seja clara.
- Escalabilidade: acrescente novos domínios sem tocar nos existentes.
- Teste: cada slice pode ter seu conjunto de testes independentes.
- Migração de estado: planeje como migrar estruturas quando necessário (versões de store, migrations simples de shape).
Resumo prático: inicie com stores modulares por domínio, normalize APIs de acesso e utilize middlewares com parcimônia para não sobrecarregar o runtime.
Gostou do guia? Continue explorando o universo Zustand
Confira outros posts para aprofundar práticas, comparar padrões entre Zustand e alternativas, e ver casos reais de uso em aplicações modernas.
Leia também:
Principais padrões com Zustand •
Zustand vs Redux: quando escolher cada um •
Otimização de re-renderização com selectors.
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!