React 19 de Cero a Experto / React 19 moderno
use(): el hook que rompe las reglas
Todos los hooks que conoces siguen las mismas reglas: solo en el nivel superior, nunca dentro de un
if. React 19 introduce uno que las ROMPE a propósito: use(). Puede leer una promesa
directamente (y suspender el componente hasta que resuelva), puede leer un contexto, y —único entre
los hooks— puede llamarse dentro de condicionales y bucles. Hoy entiendes qué hace, por qué es la
excepción, y cómo se conecta con Suspense.
Un hook con pase VIP
Leer una promesa con use()
El uso estelar: use(promesa) "desenvuelve" una promesa y te da su valor resuelto, directamente en
el render. Si la promesa aún no resolvió, el componente SE SUSPENDE y React muestra el fallback
del <Suspense> que lo envuelve:
import { use, Suspense } from "react";
// una promesa creada FUERA del componente (o pasada por props / cacheada)
const promesaGastos: Promise<Gasto[]> = fetch("/api/gastos").then((r) => r.json());
function ListaGastos() {
// use() desenvuelve la promesa: si no resolvió, el componente se suspende
const gastos = use(promesaGastos);
return (
<ul>
{gastos.map((g) => <li key={g.id}>{g.nombre}: {g.valor}</li>)}
</ul>
);
}
export default function App() {
return (
// mientras la promesa de ListaGastos no resuelve, se ve el fallback
<Suspense fallback={<p>Cargando gastos…</p>}>
<ListaGastos />
</Suspense>
);
}Fíjate en lo que NO hay: ni useState de cargando, ni useEffect, ni el patrón de tres estados
de la lección anterior. use(promesaGastos) te da los datos directamente; mientras la promesa está
pendiente, <Suspense> muestra "Cargando gastos…"; si la promesa rechaza, un Error Boundary
cercano atrapa el error. React coordina el "cargando" y el "error" a nivel de árbol, no componente
por componente. (Verás Suspense y Error Boundaries a fondo en el módulo 5.)
Leer un contexto (y condicionalmente)
El otro uso de use(): leer un Context. Aquí sí se nota que rompe las reglas —puede ir dentro de
un if, cosa que useContext no permite—:
import { use } from "react";
import { TemaContext } from "./tema";
function Boton({ destacado }: { destacado: boolean }) {
if (destacado) {
// ✅ use() PUEDE llamarse dentro de un if (useContext NO podría)
const tema = use(TemaContext);
return <button style={{ background: tema.acento }}>Destacado</button>;
}
return <button>Normal</button>;
}use(TemaContext) lee el contexto igual que useContext(TemaContext), pero al no depender del orden
posicional de los hooks, puede vivir dentro de un if o un bucle. Es la razón técnica por la que
use no lleva el prefijo de "hook con reglas estrictas" de los demás: internamente React lo maneja
distinto. (Verás Context en detalle en el módulo 6; por ahora, quédate con que use es la forma
flexible de leerlo.)
¿Qué hace use(promesa) y qué necesita Suspense para funcionar?
Mini-reto
Razona el flujo (o pruébalo en tu proyecto React 19): 1) crea una promesa const datos = obtener()
FUERA de un componente; 2) un componente <Panel> que haga const valor = use(datos) y lo muestre;
3) envuélvelo en <Suspense fallback={<Spinner />}>. Pregúntate: ¿qué pasaría si movieras
const datos = obtener() DENTRO del componente? (Pista: una promesa nueva por render.) ¿Y quién
muestra el "cargando"?
Qué sigue
use() insinúa un mundo donde el render puede "esperar" datos. Ese mundo se despliega del todo con
los SERVER COMPONENTS: componentes que corren en el servidor, sin llegar nunca al navegador como
JavaScript. La próxima lección explica el concepto —Server Components vs Client Components— que
redefine dónde vive tu código en React moderno.