¿Cansado de lanzar props como si fueran dardos en un carrusel sin frenos? Hoy te enseño a domar el Context API y a envolverlo en un hook propio, todo con TypeScript para que tu IDE no llore cada vez que guardas. Prepárate, porque el café está más fuerte que el tipado implícito.

coffee mug and code editor on a desk - imagen ilustrativa
Foto por Daniil Komov en Unsplash

Introducción

Este tutorial parte de cero: React + TypeScript. Si ya dominas JSX pero todavía usas any como si fuera el comodín universal, sigue leyendo. Te mostraré cómo crear un contexto global para el tema de la aplicación (modo claro/oscuro) y un useTheme que hará que tus componentes respiren estilo sin sudar.

Configuración del proyecto

Abre tu terminal, hazte con create‑vite y elige la plantilla react‑ts. Si prefieres npm create vite@latest my-app -- --template react-ts no te juzgaré.

npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev

Una vez arriba, instala las dependencias que usaremos:

npm install @types/react @types/react-dom

Creación del contexto

En src/context/ThemeContext.tsx definimos la forma del estado y la firma del proveedor.

import { createContext, ReactNode, useState } from 'react';

export type Theme = 'light' | 'dark';
export interface ThemeContextProps {
  theme: Theme;
  toggleTheme: () => void;
}

export const ThemeContext = createContext(undefined);

interface ProviderProps {
  children: ReactNode;
}

export const ThemeProvider = ({ children }: ProviderProps) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => setTheme(prev => (prev === 'light' ? 'dark' : 'light'));

  return (
    
      {children}
    
  );
};
flow diagram showing provider and consumer - imagen ilustrativa
Foto por Christina @ wocintechchat.com M en Unsplash

Hook personalizado para consumir el contexto

Ahora evitamos el temido useContext(ThemeContext) en cada componente creando un wrapper tipado.

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

export const useTheme = () => {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
};
VSCode screenshot showing the hook file - imagen ilustrativa
Foto por Ilya Pavlov en Unsplash

Uso en componentes

Envuelve tu árbol con ThemeProvider en src/main.tsx (o index.tsx si usas CRA).

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ThemeProvider } from './context/ThemeContext';

ReactDOM.createRoot(document.getElementById('root')!).render(
  
    
      
    
  
);

Y en cualquier componente basta con:

import { useTheme } from '../context/ThemeContext';

const Header = () => {
  const { theme, toggleTheme } = useTheme();
  return (
    

Hola Mundo

); };

Conclusión

Ya tienes un contexto tipado, un hook de consumo y el boilerplate bajo control. La próxima vez que veas a alguien pasar theme como prop, sácale una sonrisa y recuerda que la solución estuvo a un createContext de distancia.

Referencias