Ejercicio: Compartir estado: elevar y Context
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.
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.
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.