💻 Exemplos: Capítulo 08: Context API (useContext) e Criação de Custom Hooks
Especialização Frontend com React & TypeScript • Demonstrações Práticas Executáveis
🎯 Contexto e Objetivo Prático
Criação de Context API modular com Provider fortemente tipado e Custom Hook defensivo para controle global de tema.
💻 Código Fonte React 19 (TSX)
// ThemeContext.tsx
import React, { createContext, useContext, useState, useEffect } from "react";
export type ThemeMode = "light" | "dark" | "system";
export interface ThemeContextValue {
theme: ThemeMode;
resolvedTheme: "light" | "dark";
setTheme: (theme: ThemeMode) => void;
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextValue | null>(null);
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<ThemeMode>("system");
const resolvedTheme =
theme === "system"
? typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: theme;
const toggleTheme = () => {
setTheme(prev => (prev === "dark" ? "light" : "dark"));
};
const value: ThemeContextValue = {
theme,
resolvedTheme,
setTheme,
toggleTheme
};
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
// Custom Hook Defensivo: Garante consumo estrito dentro do Provider
export function useTheme(): ThemeContextValue {
const context = useContext(ThemeContext);
if (!context) {
throw new Error("useTheme() deve ser executado obrigatoriamente dentro de um <ThemeProvider>.");
}
return context;
}
// Componente Consumidor
export function ThemeToggleButton() {
const { resolvedTheme, toggleTheme } = useTheme();
return (
<button
onClick={toggleTheme}
className="px-3 py-1.5 rounded-lg border text-xs font-semibold"
>
Tema Atual: {resolvedTheme.toUpperCase()} (Clique para alternar)
</button>
);
}
🖥️ Saída de Renderização Visual e Comportamento
[ThemeProvider Ativo]
Tema Resolvido: DARK
[Tema Atual: DARK (Clique para alternar)]
(Se invocado fora do Provider, dispara TypeError defensivo com mensagem clara)