Novedades en React 19 - Un resumen completo de todas las características principales y cambios disruptivos
Receta
React 19 es una versión importante que introduce arquitectura orientada al servidor, nuevos hooks y optimizaciones automáticas. Aquí está la lista de referencia rápida de todas las características que llegaron:
Característica Categoría
-------------- ---------
Server Components (RSC) Arquitectura
Server Actions Mutaciones de datos
Form Actions Integración DOM
use() hook Obtención de datos / contexto
useActionState Gestión del estado del formulario
useFormStatus Interfaz de usuario pendiente
useOptimistic Actualizaciones optimistas
ref como prop Simplificación de API
Document Metadata SEO / gestión de head
Asset Loading APIs Rendimiento
React Compiler Auto-memoizaciónCuándo usarlo: Lee esta página primero cuando inicies un nuevo proyecto en React 19 o planifiques una migración desde React 18.
Ejemplo de trabajo
// Un componente que toca muchas características de React 19 a la vez
import { use, useOptimistic, useActionState } from "react";
import { saveComment } from "./actions"; // server action
type Comment = { id: string; text: string };
function CommentThread({ commentsPromise }: { commentsPromise: Promise<Comment[]> }) {
// use() desenvuelve la promesa (consciente de Suspense)
const comments = use(commentsPromise);
// useOptimistic para retroalimentación instantánea
const [optimistic, addOptimistic] = useOptimistic(
comments,
(state, newText: string) => [...state, { id: "temp", text: newText }]
);
// useActionState para conectar una server action
const [_state, formAction, isPending] = useActionState(
async (_prev: Comment[], formData: FormData) => {
const text = formData.get("text") as string;
addOptimistic(text);
await saveComment(text);
return [...comments, { id: crypto.randomUUID(), text }];
},
comments
);
return (
<section>
{/* Los metadatos del documento se elevan a <head> automáticamente */}
<title>Comentarios ({optimistic.length})</title>
<meta name="description" content="Hilo de comentarios en vivo" />
<ul>
{optimistic.map((c) => (
<li key={c.id}>{c.text}</li>
))}
</ul>
<form action={formAction}>
<input name="text" required />
<button disabled={isPending}>Publicar</button>
</form>
</section>
);
}
// ref como prop - no se necesita forwardRef
function FancyInput({ placeholder, ref }: { placeholder: string; ref?: React.Ref<HTMLInputElement> }) {
return <input placeholder={placeholder} ref={ref} />;
}
export { CommentThread, FancyInput };Lo que esto demuestra:
use()desenvuelve una promesa dentro de un componenteuseOptimisticpara retroalimentación instantánea de la interfazuseActionStatevinculando una server action a un formulario- Metadatos del documento (
<title>,<meta>) renderizados en línea refrecibido como un prop regular sinforwardRef
Análisis detallado
Cómo funciona
- Server Components se ejecutan exclusivamente en el servidor y envían interfaz serializada al cliente. Pueden acceder a bases de datos, sistemas de archivos y secretos directamente sin exponerlos al navegador.
- Server Actions son funciones asincrónicas marcadas con
"use server"que el framework convierte en endpoints RPC. Se pueden pasar a formularios, llamadas desde manejadores de eventos o invocadas desde transiciones. - Form Actions te permiten pasar una función asincrónica a
<form action={fn}>. React gestiona el estado pendiente, el manejo de errores y las actualizaciones optimistas automáticamente. - use() es una nueva API (no es técnicamente un hook -- se puede llamar condicionalmente) que lee promesas y valores de contexto. Al leer una promesa, se integra con límites de Suspense.
- useActionState reemplaza el
useFormStateexperimental. Devuelve[state, action, isPending]y funciona tanto en el cliente como con mejora progresiva en el servidor. - useFormStatus expone el estado pendiente del
<form>padre más cercano a cualquier componente descendiente. - useOptimistic proporciona un patrón para mostrar un valor optimista mientras una acción asincrónica está en curso, revirtiendo automáticamente si la acción falla.
- ref como prop significa que
forwardRefya no es requerido. Los componentes de función recibenrefcomo un prop regular.forwardRefaún funciona pero está deprecado y se eliminará en una versión futura. - Document Metadata etiquetas (
<title>,<meta>,<link>) renderizadas en cualquier lugar del árbol de componentes se elevan automáticamente a<head>. - Asset Loading APIs (
preload,preinit,prefetchDNS,preconnect) dereact-domte permiten cargar con entusiasmo fuentes, scripts y hojas de estilo. - React Compiler (anteriormente React Forget) auto-memoiza componentes y hooks automáticamente, eliminando la necesidad de
useMemo,useCallbackyReact.memomanuales en la mayoría de los casos.
Variaciones
React 19 funciona en dos modos principales:
- SPA solo cliente -- Obtienes form actions,
use(), actualizaciones optimistas, elevación de metadatos y el compilador. Sin server components ni server actions. - Framework full-stack (Next.js, Remix, etc.) -- Además obtienes server components y server actions con SSR de transmisión.
Notas de TypeScript
- React 19 incluye
@types/reacty@types/react-domactualizados (versión 19+). Instálalos juntos. refahora es parte del tipo de props. Si usasReact.ComponentProps<typeof MyComponent>, incluirárefautomáticamente.useActionStatees genérico:useActionState<State>(action, initialState).- La función
use()es genérica:use<T>(resource: Promise<T> | React.Context<T>): T.
Errores comunes
- Mejoras de errores de hidratación -- React 19 registra un único error de estilo diff en lugar de múltiples mensajes crípticos. Arreglo: Actualiza para ver errores más limpios, pero aún debes corregir las desincronizaciones.
- Strict Mode disparando doble -- Aún presente en desarrollo. Arreglo: Asegúrate de que los efectos sean idempotentes; esto no cambió desde React 18.
- useActionState vs useFormState --
useFormStatefue renombrado. Arreglo: Reemplaza todas las importaciones deuseFormStateconuseActionStatedesde"react"(no"react-dom"). - Deprecación de forwardRef --
forwardRefaún funciona pero desencadena una advertencia de deprecación en desarrollo. Arreglo: Refactoriza para aceptarrefcomo un prop regular. - Context como provider --
<Context>ahora se puede renderizar directamente en lugar de<Context.Provider>. La sintaxis.Provideraún funciona pero está deprecada. Arreglo: Reemplaza<MyContext.Provider value={v}>con<MyContext value={v}>. - Funciones de limpieza de ref -- Los callbacks de ref ahora pueden devolver una función de limpieza (como efectos). Devolver cualquier otra cosa (incluyendo
undefinedimplícitamente) será marcado. Arreglo: Si tu callback de ref no devuelve nada, asegúrate de que explícitamente devuelvaundefinedo devuelva una limpieza.
Alternativas
| Enfoque | Cuándo elegir |
|---|---|
| Permanecer en React 18 | Aplicación grande sin necesidad inmediata de server components o nuevos hooks |
| Adopción incremental | Agrega "use client" a componentes existentes y adopta características de React 19 archivo por archivo |
| Reescritura completa con RSC | Proyecto greenfield usando Next.js 15+ o un framework con soporte RSC |
| React 19 solo cliente | SPA que se beneficia de use(), actualizaciones optimistas y el compilador sin infraestructura de servidor |
Preguntas frecuentes
¿Cuál es el cambio arquitectónico principal en React 19 en comparación con React 18?
- React 19 introduce una arquitectura orientada al servidor con Server Components (RSC) como el modelo de renderizado predeterminado
- Los componentes se ejecutan en el servidor de forma predeterminada y envían cero JavaScript al navegador a menos que estén marcados con
"use client" - Esto se complementa con Server Actions para mutaciones de datos, eliminando la necesidad de rutas API separadas en muchos casos
¿Qué nuevos hooks y APIs llegaron en React 19?
use()para leer promesas y contexto (se puede llamar condicionalmente)useActionStatepara gestión del estado del formulario (reemplazauseFormState)useFormStatuspara interfaz de usuario pendiente en descendientes del formulariouseOptimisticpara actualizaciones optimistas instantáneas- Asset loading APIs:
preload,preinit,prefetchDNS,preconnect
¿Puedo usar características de React 19 sin un framework de servidor como Next.js?
- Sí. En una SPA solo cliente obtienes form actions,
use(), actualizaciones optimistas, elevación de metadatos y el React Compiler - Server Components y Server Actions requieren un framework con soporte RSC (p. ej., Next.js 15+, Remix)
¿Qué pasó con useFormState? Veo referencias a useActionState en su lugar.
useFormStatefue renombrado auseActionStateantes de la versión estable- Importa desde
"react", no desde"react-dom" - La firma es
useActionState(action, initialState)devolviendo[state, action, isPending]
¿Cómo funcionan los metadatos del documento en línea en React 19?
Las etiquetas como <title>, <meta> y <link> renderizadas en cualquier lugar del árbol de componentes se elevan automáticamente a <head>:
function Page() {
return (
<div>
<title>Mi página</title>
<meta name="description" content="¡Hola!" />
<h1>Contenido</h1>
</div>
);
}¿Todavía necesito forwardRef en React 19?
- No. Los componentes de función ahora reciben
refcomo un prop regular forwardRefaún funciona pero está deprecado y se eliminará en una versión futura- Migra moviendo
refdel segundo argumentoforwardRefal objeto props
Error común: ¿Qué sucede si devuelvo algo de un callback de ref que no es una función de limpieza?
- React 19 permite que los callbacks de ref devuelvan una función de limpieza (como efectos)
- Devolver cualquier otra cosa (incluyendo devolver
undefinedimplícitamente desde una expresión de función flecha) será marcado como una advertencia - Asegúrate de que tu callback de ref devuelva nada explícitamente o devuelva una función de limpieza
Error común: ¿Strict Mode aún dispara doble los efectos en React 19?
- Sí. El doble disparo de Strict Mode en desarrollo no cambió desde React 18
- Los efectos deben ser idempotentes -- ejecutarlos dos veces no debe causar comportamiento diferente
- Este es un comportamiento solo de desarrollo y no afecta construcciones de producción
¿Cómo escribo useActionState genéricamente en TypeScript?
const [state, action, isPending] = useActionState<MyState>(
async (prev: MyState, formData: FormData) => {
// devuelve nuevo estado
return { ...prev, updated: true };
},
{ updated: false }
);useActionStatees genérico:useActionState<State>(action, initialState)- La firma de acción es
(prevState: State, formData: FormData) => Promise<State>
¿Cómo se escribir la función use() en TypeScript?
use<T>(resource: Promise<T> | React.Context<T>): T- El tipo resuelto se infiere del tipo de promesa o contexto
- Se importa desde
"react":import { use } from "react"
¿Qué hace el React Compiler y necesito cambiar mi código?
- El compilador (anteriormente React Forget) auto-memoiza componentes y hooks automáticamente en tiempo de construcción
- Elimina la necesidad de
useMemo,useCallbackyReact.memomanuales en la mayoría de los casos - No se requieren cambios de código -- la memoización manual existente es compatible
¿Cuál es la diferencia entre use() y useContext()?
use()se puede llamar condicionalmente (dentro de bloquesif, bucles, retornos anticipados) mientras queuseContextnouse()también acepta promesas, no solo objetos de contextouse(context)es el reemplazo preferido parauseContext(context)en adelante
¿Cómo debo abordar la migración de una aplicación grande de React 18 a React 19?
- Se recomienda adopción incremental: agrega
"use client"a componentes existentes y adopta características archivo por archivo - Instala tipos de React 19 (
@types/reacty@types/react-domversión 19+) juntos - Reemplaza importaciones de
useFormStateconuseActionStatedesde"react" - Reemplaza
<Context.Provider>con<Context value={v}>(opcional, la sintaxis antigua aún funciona)
Relacionado
- Server Components -- Modelo RSC y serialización
- Server Actions -- Funciones de servidor e integración de formularios
- Form Actions --
<form action={}>, useActionState, useFormStatus - use() Hook -- Lectura de promesas y contexto
- useOptimistic -- Patrones de actualización optimista
- React Compiler -- Auto-memoización