Llegaste al proyecto final: un chat colaborativo en tiempo real con salas, presencia y usuarios —el
que reúne todo React 19 que dominaste—. Pero antes de escribir una línea, un desarrollador senior hace
lo que separa un proyecto ordenado de un caos: PLANEA. Hoy aplicas el método de las cinco preguntas
(el mismo del cierre de JavaScript, SC-02) para diseñar la arquitectura del chat —qué estado hay, qué
es de servidor, qué componentes, qué eventos— antes de tocar el teclado.
Pensar antes de construir
Piénsalo así
Construir una app sin planear es como levantar una casa sin planos: pones paredes donde vas pudiendo y
al final descubres que el baño quedó sin tubería y la escalera no llega al segundo piso. Un arquitecto
dibuja los planos primero —dónde va cada cuarto, cómo fluye el agua, dónde las cargas— y así la
construcción es ordenada y sin sorpresas. Planear una app es dibujar esos planos: qué datos hay, quién
los tiene, cómo fluyen, qué piezas la componen. Diez minutos de planear ahorran horas de reescribir.
En una app de tiempo real —con estado que llega solo por el socket— planear es aún más valioso: hay más
piezas móviles.
Las cinco preguntas
El método para descomponer cualquier app
Ante cualquier app, respóndete cinco preguntas (SC-02, M17). Para nuestro chat:
¿QUÉ muestra la app? (las vistas) → una pantalla de login (elegir nombre), una lista de SALAS,
los MENSAJES de la sala actual, la lista de PRESENCIA (quién está en línea) y un indicador de "está
escribiendo…".
¿Cuál es la fuente de VERDAD de los datos? → los mensajes y la presencia vienen del SERVIDOR por
el socket (estado de servidor). El nombre de usuario y la sala seleccionada son estado del CLIENTE.
¿Qué OPERACIONES hay? → entrar (elegir nombre), unirse a una sala, enviar un mensaje, avisar que
escribo, salir. Cada una se traduce en un evento del socket o un cambio de estado local.
¿Cómo se RENDERIZA? → login condicional (sin nombre → formulario; con nombre → chat); la sala
actual filtra los mensajes; la presencia y el "escribiendo…" son listas/indicadores derivados de
eventos.
¿Qué EVENTOS responden a la interacción? → clic en una sala (cambiar sala + emit("unir_sala")),
enviar el formulario (emit("mensaje") + optimista), escribir en el input (emit("escribiendo")).
Con esas cinco respuestas ya tienes el esqueleto de la app —vistas, datos, operaciones, render,
eventos— antes de escribir código. Es el mismo modelo mental de MVC que viste en JavaScript, ahora con
una fuente de datos en tiempo real.
Clasificar el estado
Cada dato en su sitio (módulo 6)
Aplicando el mapa de decisión del módulo 6, el estado del chat se reparte así:
Estado local (useState) : el nombre de usuario (antes de entrar), el texto que se está escribiendo
en el input, la sala seleccionada. Datos que solo le importan a un componente o a la sesión actual.
Estado de servidor (por el socket) : los mensajes de cada sala, la lista de presencia, el
indicador de "escribiendo…". NO viven en un useState que tú controlas: LLEGAN por el socket y
actualizas el estado al recibirlos. Es el "estado prestado" del módulo 5, pero empujado en vivo.
La conexión (useRef) : el socket en sí se guarda en un ref —es un recurso vivo, no un dato que se
renderiza (módulo 3)—.
Y el vocabulario de EVENTOS que cliente y servidor comparten (módulo 9): el cliente EMITE "unir_sala",
"mensaje", "escribiendo"; y ESCUCHA "historial" (mensajes de la sala al entrar), "mensaje"
(nuevos, propios y ajenos), "presencia" (quién está) y "escribiendo" (quién teclea). Definir estos
nombres ANTES de codificar es como acordar el idioma antes de la conversación.
La estructura de archivos
Organizar por feature (módulo 10)
Aunque el proyecto quepa en un playground, en un proyecto real lo organizarías por feature (módulo 10):
features/chat/ → los componentes del chat (Sala, ListaMensajes, Mensaje, FormularioMensaje,
Presencia), el hook useSocket/useChat, los tipos (Mensaje, Usuario).
features/auth/ → la pantalla de login y el estado del usuario.
shared/ → un <Boton>, un <Avatar> genérico, utilidades.
Cada feature autocontenida, con su lógica colocada. El useChat (un custom hook, módulo 3) encapsularía
toda la gestión del socket y el estado de mensajes/presencia, de modo que los componentes solo
consumen const { mensajes, presencia, enviar } = useChat(sala) —limpio y testeable—. Planear la
estructura te obliga a pensar en esos límites antes de que el código los borre.
Al planear el chat, ¿dónde vive cada tipo de estado según su naturaleza?
A Todo en un único useState global para que sea simple B Local (useState): nombre de usuario, texto del input, sala seleccionada. De servidor (por el socket, no un useState que tú controlas): los mensajes, la presencia y el 'escribiendo…' —llegan empujados y actualizas el estado al recibirlos—. La conexión en sí va en un useRef (recurso vivo, no dato que se renderiza). Clasificar así, antes de codificar, evita mezclar estado prestado con estado propio C Todo debe ir en el servidor, el cliente no guarda nada
Mini-reto
Antes de construir, planea en papel: 1) dibuja las vistas del chat y qué componente sería cada una; 2)
para cada dato (nombre, sala actual, mensajes, presencia, texto del input, conexión), escribe si es
local, de servidor o un ref, y por qué; 3) lista el vocabulario de eventos: qué EMITE el cliente y qué
ESCUCHA. Compara tu plan con el que construiremos: si coinciden, ya piensas como arquitecto.
Qué sigue
Con el plano en mano, a construir: la próxima lección es el PROYECTO capstone —el chat colaborativo
completo con salas, mensajes, presencia y "escribiendo…", corriendo en vivo—. Todo React 19 que
dominaste, ensamblado en una app real.