Aula 19 - Gerenciamento de Estado Global Desacoplado 🌐
Objetivo Pedagógico
Objetivo: Arquitetura de estado global moderno com bibliotecas atômicas/baseadas em seletor (Zustand), eliminando boilerplate e otimizando subscrições.
📑 1. Fundamentos Teóricos & Análise Técnica
O gerenciamento de estado global em React passou por ciclos de evolução marcados por diferentes filosofias. O modelo histórico do Redux clássico, embora previsível e determinístico, impunha uma sobrecarga massiva de boilerplate (actions, action-types, action-creators, reducers, selectors e dependência de connect ou provedores contextuais).
Bibliotecas modernas como Zustand adotam uma abordagem desacoplada baseada no padrão Publish-Subscribe (Pub/Sub) fora da árvore React: 1. O estado reside em uma store independente em memória JavaScript pura, sem exigir um <Provider> encapsulando a aplicação. 2. A sincronização com o React utiliza a API interna useSyncExternalStore (introduzida no React 18), prevenindo leituras inconsistentes (tearing) durante renderizações concorrentes. 3. Os componentes se inscrevem na store através de Seletores Granulares (useStore(state => state.property)), garantindo que o componente re-renderize exclusivamente quando a propriedade selecionada sofrer mutação.
📐 Arquitetura Conceitual & Diagrama de Fluxo
graph LR
subgraph ZustandStore ["Zustand Store (Fora da Árvore React)"]
State["Estado Central: { user, cart, theme }"]
Actions["Ações: { login(), addToCart() }"]
end
ZustandStore -->|Seletor: s => s.cart| CompCart["HeaderCartBadge (Re-renderiza apenas ao alterar cart)"]
ZustandStore -->|Seletor: s => s.theme| CompTheme["ThemeSwitcher (Re-renderiza apenas ao alterar theme)"]
CompCart -.->|Dispara Ação| Actions
style ZustandStore fill:#e3f2fd,stroke:#1565c0
style CompCart fill:#e8f5e9,stroke:#2e7d32
style CompTheme fill:#fff3e0,stroke:#e65100 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Zero Provider Overhead: A store pode ser acessada tanto dentro de componentes React quanto em funções utilitárias ou interceptores HTTP fora do React. - Seletores de Estado Estritos: Redução drástica do número de re-renderizações em comparação com Context API. - Middlewares Nativos: Suporte imediato a persistência em localStorage (persist) e depuração visual no Redux DevTools. - Imutabilidade sem Verbosismo: Possibilidade de mutações declarativas simples sem necessidade de bibliotecas externas.
🛠️ 2. Implementação Prática em Zustand e Gerenciamento de Estado
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// use-cart-store.ts (Store Zustand com Seletor e Persistência)
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartItem { id: string; title: string; price: number; }
interface CartState {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
clearCart: () => void;
totalPrice: () => number;
}
export const useCartStore = create<CartState>()(
persist(
(set, get) => ({
items: [],
addItem: (item) => set((state) => ({ items: [...state.items, item] })),
removeItem: (id) => set((state) => ({ items: state.items.filter(i => i.id !== id) })),
clearCart: () => set({ items: [] }),
totalPrice: () => get().items.reduce((acc, curr) => acc + curr.price, 0)
}),
{ name: 'app-shopping-cart-storage' }
)
);
// Exemplo de consumo em componente:
// const itemsCount = useCartStore((state) => state.items.length); // Seletor granular!
💡 Análise Passo a Passo do Código
- Criação da Store Desacoplada:
create<CartState>()instancia a store tipada com estado e métodos em uma única estrutura limpa. - Middleware de Persistência:
persistarmazena e reidrata os dados automaticamente nolocalStoragedo navegador. - Assinatura Seletiva:
state.items.lengthgarante que o componente que exibe a contagem de itens não re-renderize se os preços forem atualizados.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto