Lanzamiento de React 19.2 (información de lanzamiento)

React 19.2

1 de octubre de 2025 por The React Team


React 19.2 ya está disponible en npm.

Este es nuestro tercer lanzamiento en el último año, después de React 19 en diciembre y React 19.1 en junio. En esta publicación, daremos una visión general de las nuevas características en React 19.2 y destacaremos algunos cambios notables.


Nuevas características de React

<Activity />

<Activity> te permite dividir tu aplicación en “actividades” que pueden ser controladas y priorizadas.

Puedes usar Activity como una alternativa para renderizar condicionalmente partes de tu aplicación:

// Antes
{isVisible && <Page />}

// Después
<Activity mode={isVisible ? 'visible' : 'hidden'}>
  <Page />
</Activity>

En React 19.2, Activity admite dos modos: visible y hidden.

  • hidden: oculta los hijos, desmonta los efectos y difiere todas las actualizaciones hasta que React no tenga nada más que hacer.
  • visible: muestra los hijos, monta los efectos y permite procesar las actualizaciones normalmente.

Esto significa que puedes pre-renderizar y seguir renderizando partes ocultas de la aplicación sin afectar el rendimiento de lo que es visible en pantalla.

Puedes usar Activity para renderizar partes ocultas de la aplicación a las que un usuario es probable que navegue a continuación, o para guardar el estado de las partes de las que el usuario se aleja. Esto ayuda a hacer que las navegaciones sean más rápidas cargando datos, css e imágenes en segundo plano, y permite que las navegaciones hacia atrás mantengan el estado como los campos de entrada.

En el futuro, planeamos agregar más modos a Activity para diferentes casos de uso.

Para ejemplos sobre cómo usar Activity, consulta la documentación de Activity.


useEffectEvent

Un patrón común con useEffect es notificar al código de la aplicación sobre algún tipo de “eventos” de un sistema externo. Por ejemplo, cuando una sala de chat se conecta, es posible que desees mostrar una notificación:

function ChatRoom({ roomId, theme }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      showNotification('Connected!', theme);
    });
    connection.connect();
    return () => {
      connection.disconnect()
    };
  }, [roomId, theme]);
  // ...
}

El problema con el código anterior es que cualquier cambio en los valores utilizados dentro de un “evento” como este hará que el Effect circundante se vuelva a ejecutar. Por ejemplo, cambiar el theme hará que la sala de chat se reconecte. Esto tiene sentido para los valores relacionados con la lógica del Effect en sí, como roomId, pero no tiene sentido para theme.

Para solucionar esto, la mayoría de los usuarios simplemente desactivan la regla de lint y excluyen la dependencia. Pero esto puede llevar a errores ya que el linter ya no puede ayudarte a mantener las dependencias actualizadas si necesitas actualizar el Effect más tarde.

Con useEffectEvent, puedes separar la parte del “evento” de esta lógica del Effect que lo emite:

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]); // ✅ Todas las dependencias declaradas (Effect Events no son dependencias)
  // ...
}

Similar a los eventos DOM, los Eventos de Effect siempre “ven” las últimas props y estado.

Los Eventos de Effect no deben declararse en el array de dependencias. Necesitarás actualizar a eslint-plugin-react-hooks@6.1.1 para que el linter no intente insertarlos como dependencias. Tenga en cuenta que los Eventos de Effect solo pueden declararse en el mismo componente o Hook que su Effect. Estas restricciones son verificadas por el linter.

Nota

Cuándo usar useEffectEvent

Debes usar useEffectEvent para funciones que conceptualmente sean “eventos” que ocurren al ser disparados desde un Effect en lugar de un evento de usuario (eso es lo que lo convierte en un “Effect Event”). No necesitas envolver todo en useEffectEvent, ni usarlo solo para silenciar el error del linter, ya que esto puede llevar a errores.

Para un análisis profundo sobre cómo pensar en los Eventos de Effect, consulta: Separando eventos de efectos.


cacheSignal

Componentes del Servidor de React

cacheSignal solo se usa con Componentes del Servidor de React.

cacheSignal te permite saber cuándo termina el ciclo de vida de cache():

import {cache, cacheSignal} from 'react';
const dedupedFetch = cache(fetch);
async function Component() {
  await dedupedFetch(url, { signal: cacheSignal() });
}
```Esto le permite limpiar o abortar el trabajo cuando el resultado ya no se usará en la caché, como por ejemplo:

* React ha completado con éxito el renderizado
* El renderizado fue abortado
* El renderizado ha fallado

Para obtener más información, consulte la documentación de [`cacheSignal`](https://react.dev/reference/react/cacheSignal).

---

### Rutas de Rendimiento

React 19.2 añade un nuevo conjunto de [rutas personalizadas](https://developer.chrome.com/docs/devtools/performance/extension) a los perfiles de rendimiento de Chrome DevTools para proporcionar más información sobre el rendimiento de su aplicación React:

![](upload://g2IsuokXd6iNBk64VGRI2bqzFBN.webp)

La documentación de [React Performance Tracks](https://react.dev/reference/dev-tools/react-performance-tracks) explica todo lo incluido en las rutas, pero aquí hay una visión general de alto nivel.

#### Programador de Tareas ⚛

La ruta del Programador de Tareas muestra en qué está trabajando React para diferentes prioridades, como "bloqueante" para interacciones de usuario o "transición" para actualizaciones dentro de startTransition. Dentro de cada ruta, verá el tipo de trabajo que se está realizando, como el evento que programó una actualización y cuándo se realizó el renderizado para esa actualización.

También mostramos información como cuándo una actualización está bloqueada esperando una prioridad diferente o cuándo React está esperando el pintado antes de continuar. La ruta del Programador de Tareas le ayuda a comprender cómo React divide su código en diferentes prioridades y el orden en que completó el trabajo.

Consulte la documentación de la [ruta del Programador de Tareas](https://react.dev/reference/dev-tools/react-performance-tracks#scheduler) para ver todo lo incluido.

#### Componentes ⚛

La ruta de Componentes muestra el árbol de componentes en los que React está trabajando, ya sea para renderizar o ejecutar efectos. Dentro verá etiquetas como "Montaje" cuando los hijos o efectos se montan, o "Bloqueado" cuando el renderizado está bloqueado debido a la cesión de trabajo fuera de React.

La ruta de Componentes le ayuda a comprender cuándo se renderizan los componentes o se ejecutan efectos y el tiempo que tarda en completar ese trabajo para ayudar a identificar problemas de rendimiento.

Consulte la documentación de la [ruta de Componentes](https://react.dev/reference/dev-tools/react-performance-tracks#components) para ver todo lo incluido.

---

## Nuevas Características de React DOM

### Pre-renderizado Parcial

En la versión 19.2, estamos añadiendo una nueva capacidad para pre-renderizar parte de la aplicación con antelación y reanudar el renderizado más tarde.

Esta característica se llama "Pre-renderizado Parcial" y le permite pre-renderizar las partes estáticas de su aplicación y servirla desde un CDN, y luego reanudar el renderizado del shell para llenarla con contenido dinámico más tarde.

Para pre-renderizar una aplicación y reanudarla más tarde, primero llame a `prerender` con un `AbortController`:

``````jsx
<App />
, { signal: controller.signal, });
// Guardar el estado pospuesto para más tarde
await savePostponedState(postponed);
// Enviar preludio al cliente o CDN.

Luego, puede devolver el shell prelude al cliente y luego llamar a resume para “reanudar” un flujo de SSR:

const postponed = await getPostponedState(request);
const resumeStream = await resume(<App />, postponed);
// Enviar flujo al cliente.

O puede llamar a resumeAndPrerender para reanudar y obtener HTML estático para SSG:

const postponedState = await getPostponedState(request);
const { prelude } = await resumeAndPrerender(<App />, postponedState);
// Enviar preludio HTML completo al CDN.

Para obtener más información, consulte la documentación de las nuevas APIs:

Además, las APIs de prerender ahora devuelven un estado postpone para pasar a las APIs de resume.


Cambios destacados

Agrupación de límites de suspensión para SSR

Hemos corregido un error de comportamiento en el que los límites de suspensión se revelaban de manera diferente según si se renderizaban en el cliente o durante la transmisión desde el renderizado en el servidor.

A partir de la versión 19.2, React agrupará las revelaciones de los límites de suspensión renderizados en el servidor durante un breve período, para permitir que más contenido se revele juntos y se alinee con el comportamiento de renderizado en el cliente.

Anteriormente, durante el renderizado en el servidor en transmisión, el contenido de suspensión reemplazaba inmediatamente los fallbacks.

En React 19.2, los límites de suspensión se agrupan durante un breve período, lo que permite revelar más contenido juntos.

Esta corrección también prepara las aplicaciones para admitir <ViewTransition> para Suspense durante SSR. Al revelar más contenido juntos, las animaciones pueden ejecutarse en lotes más grandes de contenido y evitar encadenar animaciones de contenido que se transmiten muy cerca.

Nota

React utiliza heurísticas para garantizar que el throttling no afecte a los principales indicadores web y el posicionamiento en los motores de búsqueda.

Por ejemplo, si el tiempo total de carga de la página se acerca a 2.5 segundos (que es el tiempo considerado “bueno” para LCP), React dejará de agrupar y revelará el contenido inmediatamente para que el throttling no sea la razón para perder la métrica.


SSR: Soporte para Web Streams en Node

React 19.2 añade soporte para Web Streams para la transmisión de SSR en Node.js:

Además de las nuevas APIs resume:

Trampa

Preferir Node Streams para el renderizado en el servidor en Node.js

En entornos Node.js, seguimos recomendando encarecidamente el uso de las APIs de Node Streams:

Esto se debe a que Node Streams son mucho más rápidos que Web Streams en Node, y Web Streams no admiten compresión por defecto, lo que lleva a que los usuarios se pierdan accidentalmente los beneficios de la transmisión.


eslint-plugin-react-hooks v6

También publicamos eslint-plugin-react-hooks@6.1.1 con configuración plana por defecto en el preset recommended, y opt-in para las reglas nuevas impulsadas por el compilador de React.

Para continuar utilizando la configuración heredada, puede cambiar a recommended-legacy:

- extends: ['plugin:react-hooks/recommended']
+ extends: ['plugin:react-hooks/recommended-legacy']

Para obtener una lista completa de las reglas habilitadas por el compilador, consulte la documentación del linter.

Consulte el registro de cambios de eslint-plugin-react-hooks para obtener una lista completa de cambios.


Actualizar el prefijo predeterminado de useId

En la versión 19.2, estamos actualizando el prefijo predeterminado de useId de :r: (19.0.0) o «r» (19.1.0) a _r_.

La intención original de usar un carácter especial que no era válido para los selectores CSS era que era poco probable que colisionara con los IDs escritos por los usuarios. Sin embargo, para admitir View Transitions, necesitamos garantizar que los IDs generados por useId sean válidos para view-transition-name y nombres XML 1.0.


Registro de cambios

Otros cambios destacados

  • react-dom: Permitir el uso de nonce en estilos hoistables #32461
  • react-dom: Advertir sobre el uso de un nodo propiedad de React como Contenedor si también tiene contenido de texto #32774

Correcciones de errores destacados

  • react: Serializar el contexto como “SomeContext” en lugar de “SomeContext.Provider” #33507
  • react: Corregir bucle infinito de useDeferredValue en el evento popstate #32821
  • react: Corregir un error cuando se pasó un valor inicial a useDeferredValue #34376
  • react: Corregir un bloqueo al enviar formularios con Client Actions #33055
  • react: Ocultar/mostrar el contenido de los límites de suspensión deshidratados si se vuelven a suspender #32900
  • react: Evitar desbordamiento de pila en árboles amplios durante Hot Reload #34145
  • react: Mejorar las pilas de componentes en varios lugares #33629, #33724, #32735, #33723
  • react: Corregir un error con React.use dentro de un componente React.lazy-ed #33941
  • react-dom: Dejar de advertir cuando se usan atributos ARIA 1.3 #34264
  • react-dom: Corregir un error con Suspense profundamente anidado dentro de fallbacks de Suspense #33467
  • react-dom: Evitar colgarse al suspender después de abortar durante el renderizado #34192

Para obtener una lista completa de cambios, consulte el Registro de cambios.