Inicio

React y el Hook useChat

Capítulo 2: React y el Hook useChat

En el capítulo anterior generamos texto con streaming en la terminal. Ahora llevaremos el streaming a React con useChat, el hook que hace que construir interfaces de chat sea casi trivial.

Por qué necesitas un hook especializado

Tu primer instinto podría ser: "Es solo un fetch con useState". Pero hay varios problemas con ese approach:

  1. No hay streaming: El usuario ve pantalla vacía hasta que termina la respuesta
  2. No hay historial estructurado: Mensajes como strings planos, sin roles ni metadata
  3. No hay manejo de errores mid-stream: ¿Qué pasa si la conexión falla a mitad?
  4. Re-renders excesivos: Cada token causa un re-render de todo el componente

useChat resuelve todo con una API declarativa:

Cambio en v6: El hook ya no maneja el input internamente. Usas useState para el campo de texto, sendMessage para enviar, status en lugar de isLoading, y los mensajes tienen parts en lugar de content.

Anatomía de useChat

El hook devuelve un objeto con estas propiedades esenciales:

Los estados de status:

  • ready: Listo para recibir input
  • submitted: Mensaje enviado, esperando respuesta
  • streaming: Recibiendo tokens del servidor
  • error: Hubo un error en la petición

El tipo Message en v6

Los mensajes usan parts en lugar de content:

Esta estructura permite mensajes más ricos que pueden contener texto, invocaciones de herramientas, y resultados — todo en el mismo mensaje.

El protocolo de streaming

useChat usa un protocolo de texto optimizado para streaming, no JSON plano. Cada línea tiene un prefijo:

PrefijoSignificado
0:Chunk de texto
2:Tool call
8:Tool result
d:Metadata final (finish reason, usage)
e:Error

JSON requiere el documento completo para parsearlo. Con este protocolo, cada línea es independiente y parseable inmediatamente.

Implementación paso a paso

1. El servidor (React Router v7)

Nota v6: convertToModelMessages reemplaza a convertToCoreMessages y ahora es async. También toDataStreamResponse() fue reemplazado por toUIMessageStreamResponse().

2. El cliente

3. Registrar la ruta

En v6, useChat() usa /api/chat por defecto.

Patrones de UI para Chat

Indicador de escritura

Scroll automático inteligente

El scroll debe respetar cuando el usuario está leyendo mensajes anteriores:

Optimización de Re-renders

useChat puede causar muchos re-renders — cada token actualiza el estado.

React.memo para mensajes

Separar mensaje en streaming

Customización

Callbacks

Transport personalizado

Cancelación

Edge Cases

Enviar mientras genera

Múltiples instancias

Persistir conversación

Error mid-stream

Resumen

ConceptoQué aprendiste
useChatHook que maneja estado y streaming de chat
sendMessageReemplaza a append — envía mensajes
statusEstados: ready, submitted, streaming, error
message.partsNuevo formato con array de partes tipadas
transportConfiguración de endpoint y headers
regenerateReemplaza a reload — reintenta última respuesta
OptimizaciónReact.memo y split components

Migración automática v5 → v6


En el próximo capítulo abriremos el capó del streaming. Usaremos Hono como microscopio para ver exactamente qué viaja por el wire—cada text-delta, cada finish-step. Cuando tu chat falle en producción, este conocimiento te salvará.

¿Ya compraste el libro?

Si compraste el libro y no encuentras tu email de descarga, ingresa tu email y te enviamos un nuevo enlace.