Especialização Frontend com React & TypeScript • React 19, Hooks, Estado Global e Next.js


🗺️ Mapa Conceitual do Tópico

flowchart TD
    ROOT["App Root"] --> PROVIDER["ThemeProvider.Provider (value)"]
    PROVIDER --> COMP_A["Componente Intermediário A"]
    COMP_A --> COMP_B["Componente Intermediário B (Zero Props!)"]
    COMP_B --> CONSUMER["BotaoTema (useTheme Hook)"]

    style PROVIDER fill:#ede7f6,stroke:#7e57c2,stroke-width:2px
    style CONSUMER fill:#e8f5e9,stroke:#4caf50,stroke-width:2px

🏛️ 1. O Problema do Prop Drilling e a Context API

Quando um dado precisa ser acessado por múltiplos componentes em diferentes níveis da árvore (como dados de usuário autenticado, tema visual ou preferências de idioma), repassá-lo manualmente via props através de componentes intermediários chama-se Prop Drilling.

A Context API resolve esse problema criando um canal direto de teletransporte de dados entre o Provider (no topo) e os Consumidores (nas folhas).


🎣 2. Criação de Custom Hooks Defensivos

Um Custom Hook é uma função JavaScript cujo nome inicia obrigatoriamente com use e que pode invocar outros Hooks nativos do React.

Encapsular o consumo do contexto em um Custom Hook defensivo garante que erros de consumo fora da árvore do Provider sejam interceptados com mensagens de erro claras em tempo de desenvolvimento.


📊 3. Matriz de Decisão: Context API vs Estado Global (Zustand/Redux)

Critério Context API Nativa Estado Global Externo (Zustand/RTK)
Instalação Zero dependências (Nativa do React) Requer pacote externo
Frequência de Atualização Baixa frequência (Temas, Auth, Idioma) Alta frequência (Carrinho, Dashboards, Canvas)
Performance de Re-render Todos os consumidores re-renderizam na mudança Re-renders cirúrgicos via seletores atômicos
Complexidade Simples Moderada a Alta

⚠️ 4. Armadilhas Comuns e Anti-Padrões de Produção

  1. Contexto Monolítico Gigantesco: Colocar toda a aplicação dentro de um único AppContext contendo centenas de estados faz com que qualquer alteração de texto re-renderize a aplicação inteira.
  2. Criação de Objetos de Valor sem Memoização: Passar value={{ theme, toggleTheme }} com objeto literal no Provider recria o objeto a cada render do pai, disparando re-renders em todos os consumidores mesmo que o valor interno não tenha mudado. Use useMemo no valor do Provider.

💡 5. Diretrizes de Engenharia (Meta & React Docs)

  • Segregue Dados de Funções de Ação: Considere criar um CartStateContext (apenas leitura de itens) e um CartDispatchContext (apenas dispatch de ações), evitando que componentes que apenas disparam ações re-renderizem quando o estado mudar.
  • Lance Erro Descritivo no Custom Hook: Sempre valide if (!context) throw new Error("useMeuContext deve estar dentro do Provider").

💻 6. Demonstração Arquitetural do Conceito

// UserContext.tsx - Contexto defensivo completo
import React, { createContext, useContext, useState } from "react";

interface UserContextType {
  user: string | null;
  login: (name: string) => void;
}

const UserContext = createContext<UserContextType | null>(null);

export function useUser(): UserContextType {
  const ctx = useContext(UserContext);
  if (!ctx) throw new Error("useUser deve ser consumido dentro de UserProvider");
  return ctx;
}

📋 7. Cheat-Sheet da Context API

  • 🔹 createContext<T | null>(null): Cria o canal tipado.
  • 🔹 <Context.Provider value={memoizedValue}>: Fornece os dados na árvore.
  • 🔹 useContext(Context): Consome o dado na folha.
  • 🔹 Custom Hook wrapper: Blinda o consumo contra uso indevido.

🔍 8. Diagnóstico de Performance & React DevTools Profiler

Identificação de gargalos em Contextos:

  • Re-render em Massa: Se todos os consumidores do contexto renderizarem a cada tecla digitada, divida o contexto em fatias menores ou migre o estado frequente para uma store atômica com Zustand.
  • Context Display Name: Defina MeuContexto.displayName = "AuthContext" para facilitar a inspeção na árvore do DevTools.

🧪 9. Casos de Teste e Cenários de Borda Recomendados

  • 🔍 Consumo Fora do Provider: Valide se o Custom Hook lança uma exceção explicativa com a mensagem esperada no teste unitário.
  • 🔍 Providers Aninhados: Teste o comportamento de sobreposição quando dois Providers do mesmo contexto são aninhados.
  • 🔍 Troca Dinâmica de Tema: Valide a persistência da preferência do usuário no localStorage.