Domina el mecanismo de suspensión, la carga diferida de componentes y la división del bundle.
Abrir esta lección en KodokonSuspense se apoya en un mecanismo poco conocido: un componente que aún no tiene sus datos o su código suspende su renderizado. Bajo el capó, la implementación actual lanza una promesa, que React intercepta igual que interceptaría un error. React sube entonces hasta el límite <Suspense> más cercano, muestra su fallback, y luego reproduce el renderizado del subárbol una vez que la promesa se resuelve. Es un detalle de implementación (nunca lances una promesa tú mismo), pero explica todo el comportamiento observable: el límite actúa como un catch declarativo para el trabajo asíncrono. El caso de uso histórico es el code splitting con React.lazy.
import { lazy, Suspense } from 'react';
const Chart = lazy(() => import('./Chart'));
function Dashboard() {
return (
<Suspense fallback={<Spinner />}>
<Chart points={data} />
</Suspense>
);
}lazy espera una función que devuelve una promesa que resuelve a un módulo con una exportación default. La división en sí es tarea del bundler: cada import() dinámico se convierte en un punto de división y produce un chunk separado, cargado bajo demanda. Una sutileza frecuente en las bases de código reales: tus componentes suelen ser exportaciones con nombre. Entonces necesitas adaptar el módulo sobre la marcha.
const Chart = lazy(() =>
import('./charts').then((module) => ({
default: module.Chart,
}))
);La parte delicada en producción: durante una navegación, un contenido que ya se muestra puede volver a suspenderse (nueva ruta, nuevo chunk) y ser reemplazado bruscamente por el fallback. Desde React 18, una actualización envuelta en startTransition cambia este comportamiento: React mantiene la interfaz anterior en pantalla mientras el nuevo renderizado se suspende en segundo plano, y solo muestra el fallback para el contenido que nunca se ha revelado. Los límites también se componen en profundidad: varios límites <Suspense> anidados permiten revelar la interfaz zona por zona, desde el esqueleto global hasta los detalles.
const [isPending, startTransition] = useTransition();
function openTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
// The current tab stays visible while the new
// one loads, instead of dropping back to the fallback.React.lazy?