Aula 17 - Hooks Customizados Avançados e Contexto Isolado ⚛️
Objetivo Pedagógico
Objetivo: Arquitetura e composição de Custom Hooks avançados, isolamento de escopo com Context API modular e regras estritas de renderização.
📑 1. Fundamentos Teóricos & Análise Técnica
Os Custom Hooks no React representam o principal mecanismo para compartilhamento de lógica com estado (stateful logic) entre componentes sem a necessidade de alterar a hierarquia visual da árvore de renderização. Ao contrário dos componentes de classe legados baseados em Mixins ou Higher-Order Components (HOCs), os Custom Hooks compõem primitivas fundamentais (useState, useReducer, useEffect, useRef, useCallback) em funções puras e coesas.
O uso ingênuo de Context API, contudo, introduz problemas graves de desempenho. Quando um valor em um Context.Provider sofre mutação, todos os componentes consumidores que chamam useContext são forçados a re-renderizar, independentemente de estarem utilizando a propriedade específica que mudou.
Para solucionar esse gargalo em aplicações profissionais: 1. Separação de Contextos: Divisão de estados em dois contextos paralelos — um para o Estado (StateContext) e outro para os Despachantes de Ação (DispatchContext). 2. Contextos Isolados por Feature: Em vez de um único contexto global monolítico, instanciar provedores locais escopados aos limites do módulo. 3. Seletores Granulares: Implementação de hooks customizados que extraem apenas fatias necessárias do estado.
📐 Arquitetura Conceitual & Diagrama de Fluxo
graph TD
subgraph ArquiteturaContexto ["Padrão de Contexto Isolado em React"]
Provider["OrderProvider (Provedor Escopado)"] --> StateCtx["OrderStateContext (Dados)"]
Provider --> DispatchCtx["OrderDispatchContext (Funções de Ação)"]
end
StateCtx --> HookState["useOrderState() -> Lê Dados do Pedido"]
DispatchCtx --> HookDispatch["useOrderDispatch() -> Dispara Ações (Nunca re-renderiza por dados!)"]
HookState --> CompViewer["ViewComponent (Re-renderiza apenas se dados mudarem)"]
HookDispatch --> CompButton["ActionButton (Zero re-renderizações desnecessárias!)"]
style ArquiteturaContexto fill:#e3f2fd,stroke:#1565c0
style CompViewer fill:#fff3e0,stroke:#e65100
style CompButton fill:#e8f5e9,stroke:#2e7d32 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Composição Funcional de Hooks: Encapsulamento de efeitos colaterais, sincronização com APIs e ciclo de vida. - Desacoplamento State vs. Dispatch: Componentes que apenas disparam ações não devem assinar as atualizações de estado. - Regras Estritas de Hooks: Chamadas restritas ao nível superior de componentes ou outros custom hooks. - Abstração Limpa de Efeitos: Ocultação de detalhes de implementação como AbortController dentro de hooks especializados.
🛠️ 2. Implementação Prática em React 18+ Hooks e Context API
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// use-fetch-abortable.ts (Custom Hook com Cancelamento Automático)
import { useState, useEffect, useRef } from 'react';
export function useFetchAbortable<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const controller = new AbortController();
setLoading(true);
fetch(url, { signal: controller.signal })
.then(res => {
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
return res.json() as Promise<T>;
})
.then(resData => {
setData(resData);
setError(null);
})
.catch(err => {
if (err.name !== 'AbortError') {
setError(err);
}
})
.finally(() => setLoading(false));
// Cleanup: cancela a requisição se o componente desmontar
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
💡 Análise Passo a Passo do Código
- AbortController Dedicado: A cada mudança da prop
url, uma nova instância deAbortControlleré criada para monitorar a requisição. - Cleanup Eficiente: A função retornada pelo
useEffectaborta requisições pendentes se o usuário trocar de página rapidamente. - Tratamento de AbortError: Erros de cancelamento proposital são ignorados para não poluir o estado visual do componente.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto