CodeForge

React 19 de Cero a Experto / Tiempo real y sistemas distribuidos

Un chat en vivo con envío optimista

Teoría22 min20 XP

Con el useSocket listo, armar un chat es juntar piezas que ya dominas: una lista de mensajes que crece con lo que llega, un formulario para enviar, y —para que se sienta instantáneo— envío OPTIMISTA (tu mensaje aparece al toque, antes de que el servidor confirme, como en el módulo 4). Hoy construyes un chat fluido en vivo y ves cómo el tiempo real y la UI optimista se combinan.

Hablar sin esperar el eco

El chat, en vivo

Este chat usa el socket simulado con envío optimista: tu mensaje aparece marcado como "enviando…" y se confirma cuando el "servidor" lo devuelve. El bot responde para simular a otra persona:

Envía mensajes: aparecen al instante a la derecha con (optimista), se confirman (~0.3s) quitando el reloj, y el bot responde a la izquierda (~1.1s). El truco del optimismo: al enviar, agregas el mensaje con un id y enviando: true; cuando el "servidor" te devuelve ese mismo id, lo reconoces y quitas la marca (en vez de duplicarlo). Los detalles de UX —alinear los míos a la derecha, auto-scroll al último con scrollIntoView— son lo que hace que un chat se sienta pulido.

En un chat, ¿cómo evitas que tu propio mensaje aparezca DUPLICADO al usar envío optimista?

Mini-reto

Pule el chat: 1) agrega la hora a cada mensaje (new Date().toLocaleTimeString()) y muéstrala bajo el texto; 2) deshabilita el botón "Enviar" si el input está vacío; 3) bonus: si un mensaje propio no se confirma en 3 segundos (simúlalo con un caso que el "servidor" ignore), márcalo como "no enviado ❌" con un botón para reintentar. Observa cómo el id compartido hace posible rastrear el estado de cada mensaje.

Qué sigue

Tu chat funciona, pero le falta el toque social: saber QUIÉN está en línea y ver "Luis está escribiendo…". La próxima lección trae la PRESENCIA y las SALAS (rooms) —cómo agrupar usuarios en canales y mostrar quién está conectado—, las piezas que faltan para el chat colaborativo del proyecto final.