Saltar al contenido
Curso de React
Todos los cursos

Ejercicio: Compartir estado: elevar y Context

  • ⏱ 35 minutos
  • 📶 Nivel: principiante

Objetivo

Compartir un tema entre componentes lejanos con Context, un proveedor propio y un hook.

Cómo se trabaja

Escribe un componente llamado App (puedes crear los demás que necesites). Prueba tu código en el editor de abajo; cuando funcione, pega todo el archivo en el comprobador. Los import de react se aceptan y se ignoran, porque aquí React ya está cargado.

⚛️ Tu editor de React (empieza desde aquí)
Consola

Pasos

Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.

💡 Pista 1: App y el tema

App también necesita leer el tema para poner la clase. Crea un componente interior (por ejemplo Pantalla) que use useTema() y envuélvelo con <TemaProvider> en App.

💡 Pista 2: alternar

Usa la forma funcional: setTema(t => t === "claro" ? "oscuro" : "claro").

🔎 Comprueba tu trabajo

Pega tu código y pulsa Comprobar. La revisión ocurre en tu navegador; nada se envía a ningún sitio. Cada punto en rojo incluye una pista.

    ✅ Ver una solución posible

    Intenta resolverlo antes de mirar. Tu versión puede ser distinta y también correcta.

    App.jsx
    import { createContext, useContext, useState } from "react";
    
    const TemaContext = createContext(null);
    
    function TemaProvider({ children }) {
      const [tema, setTema] = useState("claro");
      const alternar = () => setTema((t) => (t === "claro" ? "oscuro" : "claro"));
      return <TemaContext.Provider value={{ tema, alternar }}>{children}</TemaContext.Provider>;
    }
    
    function useTema() {
      return useContext(TemaContext);
    }
    
    function Etiqueta() {
      const { tema } = useTema();
      return <p className="etiqueta">Tema: {tema}</p>;
    }
    
    function Interruptor() {
      const { alternar } = useTema();
      return <button onClick={alternar}>Cambiar tema</button>;
    }
    
    function Pantalla() {
      const { tema } = useTema();
      return (
        <main className={"app " + tema}>
          <Etiqueta />
          <Interruptor />
        </main>
      );
    }
    
    export default function App() {
      return (
        <TemaProvider>
          <Pantalla />
        </TemaProvider>
      );
    }

    💡 🏁 Reto extra (opcional)

    Guarda el tema en localStorage con un efecto dentro de TemaProvider y léelo como estado inicial.