El Muro de Serialización: Props RSC
hard⏱ 20 minreactlesson
Una página de pedidos (Server Component) renderiza un <OrderTable> de cliente — y le entrega tres props que no sobreviven la serialización: un callback (onSelect), instancias de Date y un Map. El preview de un solo proceso lo renderiza feliz, y eso es exactamente lo que hace traicionero a este bug: en un build real del App Router la prop de función lanza "Functions cannot be passed directly to Client Components", y las props Date/Map dejan de ser Dates y Maps al otro lado.
Tus tareas:
- TODO(A) — Derriba la prop de función: el comportamiento no se serializa. Mueve la interacción de selección al módulo de cliente:
useState para el id de la fila seleccionada, onClick en la fila, feedback en el caption y una clase de highlight.
- TODO(B) — Las fechas se vuelven strings en el muro: la página envía
placedAt como string ISO; la tabla re-crea un Date local para formatearlo.
- TODO(C) — El Map se vuelve datos planos: reemplaza el
Map de etiquetas de status con un objeto plano e indexa en el cliente.
El modelo mental: la frontera servidor → cliente es un muro de serialización — solo cruzan datos tipo JSON (más unos pocos extras bendecidos por React, como promesas y JSX). Funciones, instancias de clases, Date, Map y Set no cruzan.
Why this happens
Las props de un Server Component a un Client Component viajan por el payload RSC — un formato de cable, aproximadamente JSON con algunas extensiones de React. Por eso las reglas son las que son: las funciones son comportamiento, no datos, así que no cruzan (las válvulas de escape son mover el comportamiento al componente de cliente, o pasar una Server Action creada con "use server"); Date/Map/Set son objetos vivos con métodos, así que llegan convertidos en otra cosa — o rompen el build directamente. La moneda confiable son los datos planos: objetos, arrays, strings, números, booleanos, null. De ahí salen dos modismos. Primero, el estado que existe puramente para la interacción (qué fila está seleccionada) pertenece al componente de cliente que lo usa — el servidor no tiene por qué poseerlo. Segundo, los tipos ricos se aplanan en el muro (Date → string ISO, Map → objeto plano) y se rehidratan del lado del cliente. Y nota la trampa sobre la que está construido este reto: un preview de desarrollo de un solo proceso no puede atrapar estos bugs — solo la frontera real de serialización lo hace.