Shell de Cliente, Children de Servidor: el Patrón de Slot
medium⏱ 20 minreactlesson
Una vista de lectura donde un shell de cliente diminuto (un toggle de tema) se tragó el artículo entero renderizado en servidor: el shell importa y renderiza ArticleBody él mismo, y en RSC cualquier módulo importado desde un módulo de cliente se vuelve código de cliente también. Resultado: un artículo pesado y estático viaja al navegador y se re-renderiza con cada toggle de tema.
Tus tareas:
- TODO(A) — Abre un slot en el shell:
ThemePanel acepta { children } y lo renderiza dentro del marco con tema, en lugar de renderizar el artículo él mismo.
- TODO(B) — Reapunta la arista de import: el pseudo-import de
ArticleBody sale del shell y entra a la página — servidor importando servidor mantiene el artículo fuera del bundle de cliente.
- TODO(C) — Compón en la página:
<ThemePanel><ArticleBody /></ThemePanel> — shell de cliente por fuera, children de servidor por dentro.
Este es el patrón de children-slot, la respuesta estándar a "¿cómo muestra contenido de servidor un componente de cliente?": un Client Component no puede importar un Server Component, pero sí puede recibir JSX de servidor ya renderizado a través de una prop y dejarlo pasar intacto.
Why this happens
La frontera de cliente se propaga por los imports, no por el anidamiento de JSX — esa asimetría es toda la lección. Cuando un módulo de cliente importa un componente, ese componente debe volverse código de cliente, porque el navegador necesitará re-ejecutarlo cada vez que el shell se re-renderice. Pero el JSX pasado como prop es diferente: el servidor renderiza <ArticleBody /> primero, y el shell de cliente recibe su salida ya serializada — un valor opaco que puede posicionar pero nunca re-ejecutar. Por eso además el toggle de tema re-ejecuta solo ThemePanel: children es el mismo valor de prop a través de esos re-renders, así que React ni siquiera reconcilia dentro del subárbol del artículo, mucho menos lo envía como JavaScript. El patrón generaliza a todo componente de cliente con forma de provider — providers de tema, providers de contexto, wrappers de animación, layouts interactivos: hazlos aceptar children, mantén las aristas de import servidor → servidor, y el bundle de cliente queda como un shell interactivo delgado alrededor de HTML de servidor.