eis que ando trabalhando com React no front-end e agora o foco da equipe é usar Zustand pra fazer gerenciamento de estados, deixando o Redux de lado.

beleza, preciso aprender esse trem. então vamo lá dar uma lida na documentação. esse é só um registro pessoal do início dos meus estudos 🙂
getting started
a primeira coisa que a documentação comenta é sobre o store. o store é um hook em que dá pra definir estados, funções, etc. pra serem consumidos nos componentes. é o seu “mercado” de possibilidades, que oferece contextos diversos pra aplicação.
import { create } from 'zustand' |
pra consumir a informação dos stores no seu componente, a documentação aponta o uso do hook useStore:
function BearCounter() { |
comparison
aqui a documentação compara o Zustand com outras libs de gerenciamento de estado, particularmente nos tópicos state model e render optimization. resumindo aqui as comparações na tabela abaixo:
| ferramenta | state model | render optimization |
| Redux | baseado num modelo de dados imutável, assim como o Zustand. contudo, o Redux requer que o app seja encapsulado em providers de contexto (o Zustand não) | em ambos Zustand e Redux é recomendado que você manualmente aplique otimizações de render usando seletores |
| Valtio | baseado num modelo de dados mutável, diferente do Zustand | o Valtio usa proxies do Javascript para rastrear automaticamente quais propriedades do estado são lidas em cada componente, enquanto o Zustand recomenda que as otimizações sejam feitas através de seletores |
| Jotai | o Zustand trabalha com uma store única, enquanto o Jotai consiste em átomos primitivos que podem ser combinados entre si | o Jotai faz otimizações de renderização por meio da dependência de átomos, enquanto o Zustand recomenda que as otimizações sejam feitas através de seletores |
| Recoil | Recoil depende de string keys e precisa envolver o aplicativo em um provider de contexto | o Recoil faz otimizações de renderização por meio da dependência de átomos, enquanto o Zustand recomenda que as otimizações sejam feitas através de seletores |
updating state
pra fazer atualizações simples, a função set dá conta. ela consegue fazer atualizações no primeiro nível!
na store definimos uma ação que vai fazer a atualização do estado (no exemplo abaixo vamos considerar a ação updateFirstName):
const usePersonStore = create<State & Action>((set) => ({ |
no componente que consome a função da store:
function App() { |
outro rolê mais específico é fazer updates de estado em um objeto profundamente aninhado, tipo esse:
type State = { |
semelhante ao React ou Redux, a abordagem normal é copiar cada nível do objeto de estado e usar spread operator … pra mesclar os novos valores de estado. contudo, tem outras alternativas pra facilitar essa escrita de código: a documentação cita Immer, optics-ts e Ramda.
flux inspired practices
segundo a documentação, apesar do Zustand se considerar uma lib “unopinionated”, alguns padrões são recomendados:
1. single store
idealmente, o estado global da aplicação deve estar localizado em uma única store. contudo, se a aplicação for muuuito grande, o Zustand permite que a store seja dividida em slices menores.
2. use set / setState to update the store
sempre use set (ou setState) para realizar atualizações na store. essas funções garantem que a atualização seja corretamente mesclada e que quem está consumindo seja notificado adequadamente.
3. colocate store actions
no Zustand, o estado pode ser atualizado sem o uso de ações dispatch e redutores encontrados em outras bibliotecas. essas ações podem ser adicionadas diretamente na store:
const useBoundStore = create((set) => ({ |
opcionalmente, usando setState, elas podem ser localizadas externamente à store.
practice with no storage actions
a documentação trabalha com duas abordagens pra alocar as ações na store, bora ver:
1. ações junto com os estados dentro da store
é o que o Zustand recomenda, a priori.
me PARECE mais organizado manter os estados e as ações unidos, porque talvez facilite manutenções, criação de novas ações etc. fica tudo encapsulado em um lugar só:
export const useBoundStore = create((set) => ({ |
nesse caso, você teria que chamar o hook pra consumir as ações.
2. ações no nível do módulo fora da store
essa abordagem alternativa não exige um hook pra consumir a ação, mas talvez seja menos encapsulada:
export const useBoundStore = create(() => ({ |
segundo a documentação, não há pontos negativos em usar um ou outro, parece mais uma questão de preferência mesmo.
conclusiones
por hoje é isso, pessoal. foi massa entender um pouco melhor sobre stores e as possibilidades de consumo desse contexto.
boa noite!