React 19.2: Todas las Novedades del Tercer Major Release de 2025
Hola HaWkers, React 19.2 llegó en octubre de 2025, marcando el tercer lanzamiento significativo en el último año tras React 19 en diciembre de 2024 y React 19.1 en junio de 2025.
¿Ya actualizaste tus proyectos? Vamos a explorar las nuevas features que prometen cambiar cómo construimos aplicaciones React.
Visión General de React 19.2
React 19.2 continúa la evolución de la arquitectura async-first introducida en React 19, trayendo nuevas primitivas para control de renderización y performance.
Principales Adiciones
- Activity component - Nueva primitiva para organizar partes de la aplicación
- useEffectEvent - Hook para eventos dentro de effects
- cacheSignal - Control de cache para Server Components
- Performance Tracks - Nueva herramienta de profiling
- Partial Pre-rendering - Pre-renderización parcial de la aplicación
Activity Component
Activity es una nueva primitiva que permite dividir tu aplicación en "actividades" que pueden ser controladas y priorizadas.
Concepto Básico
import { Activity } from 'react';
function App() {
const [activeTab, setActiveTab] = useState('home');
return (
<div>
<TabBar activeTab={activeTab} onChange={setActiveTab} />
<Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
<HomePage />
</Activity>
<Activity mode={activeTab === 'profile' ? 'visible' : 'hidden'}>
<ProfilePage />
</Activity>
<Activity mode={activeTab === 'settings' ? 'visible' : 'hidden'}>
<SettingsPage />
</Activity>
</div>
);
}Modos de Activity
// visible - Renderiza y muestra normalmente
<Activity mode="visible">
<Content />
</Activity>
// hidden - Mantiene estado pero esconde del DOM
<Activity mode="hidden">
<Content />
</Activity>
// Transiciones suaves entre estados
function TabContent({ isActive, children }) {
return (
<Activity mode={isActive ? 'visible' : 'hidden'}>
{children}
</Activity>
);
}
Beneficios de Activity
1. Preservación de estado:
Diferente de renderización condicional, Activity preserva todo el estado del componente cuando está oculto.
// Problema: Estado perdido al cambiar tabs
function OldApproach({ activeTab }) {
return (
<>
{activeTab === 'form' && <FormWithState />} {/* Estado reseteado */}
</>
);
}
// Solución: Activity preserva estado
function NewApproach({ activeTab }) {
return (
<Activity mode={activeTab === 'form' ? 'visible' : 'hidden'}>
<FormWithState /> {/* Estado mantenido */}
</Activity>
);
}2. Priorización de renderización:
React puede priorizar activities visibles sobre ocultas.
// Activities visibles tienen prioridad
<Activity mode="visible" priority="high">
<CriticalContent />
</Activity>
<Activity mode="hidden" priority="low">
<PreloadedContent />
</Activity>useEffectEvent
El nuevo hook useEffectEvent resuelve un problema clásico: usar valores actuales dentro de effects sin causar re-ejecución.
El Problema
// Problema: Effect re-ejecuta siempre que onMessage cambia
function Chat({ onMessage }) {
useEffect(() => {
const connection = connect();
connection.on('message', (msg) => {
onMessage(msg); // onMessage es nueva referencia a cada render
});
return () => connection.disconnect();
}, [onMessage]); // ¡Re-conecta a cada render!
}La Solución
import { useEffectEvent } from 'react';
function Chat({ onMessage }) {
// Crea referencia estable al callback
const onMessageEvent = useEffectEvent(onMessage);
useEffect(() => {
const connection = connect();
connection.on('message', (msg) => {
onMessageEvent(msg); // Siempre usa versión más reciente
});
return () => connection.disconnect();
}, []); // ¡Sin dependencias, no re-conecta!
}
Casos de Uso Prácticos
// Logging con valores actuales
function ProductPage({ productId, analytics }) {
const logVisit = useEffectEvent(() => {
analytics.logVisit(productId); // Siempre usa productId actual
});
useEffect(() => {
logVisit();
}, []);
return <Product id={productId} />;
}
// Timer con callback actualizado
function Timer({ onTick }) {
const handleTick = useEffectEvent(onTick);
useEffect(() => {
const id = setInterval(() => {
handleTick();
}, 1000);
return () => clearInterval(id);
}, []);
}cacheSignal
El cacheSignal ofrece control fino sobre el cache de Server Components.
Uso Básico
import { cacheSignal } from 'react';
async function ProductList() {
// Señal para invalidación de cache
const signal = cacheSignal();
const products = await fetchProducts({ signal });
return (
<ul>
{products.map(p => (
<li key={p.id}>{p.name}</li>
))}
</ul>
);
}Invalidación Manual
// Server Action para invalidar cache
'use server';
import { invalidateCache } from 'react';
export async function updateProduct(id, data) {
await db.products.update(id, data);
// Invalida cache de componentes que usan esa señal
invalidateCache('products');
}Partial Pre-rendering
La feature más impactante de React 19.2 es el Partial Pre-rendering, que permite pre-renderizar partes estáticas de la aplicación.
Cómo Funciona
// Layout estático pre-renderizado
function Layout({ children }) {
return (
<html>
<head>
<title>Mi App</title>
</head>
<body>
<Header /> {/* Estático - pre-renderizado */}
<Sidebar /> {/* Estático - pre-renderizado */}
<Suspense fallback={<Loading />}>
{children} {/* Dinámico - renderizado después */}
</Suspense>
<Footer /> {/* Estático - pre-renderizado */}
</body>
</html>
);
}
Beneficios de Performance
Flujo tradicional:
- Request llega
- Servidor renderiza todo
- Envía HTML completo
- Usuario ve contenido
Con Partial Pre-rendering:
- Request llega
- Servidor envía shell pre-renderizado inmediatamente
- Usuario ve estructura instantáneamente
- Contenido dinámico carga progresivamente
// Definiendo partes estáticas vs dinámicas
export default function Page() {
return (
<>
{/* Estas partes vienen del CDN instantáneamente */}
<Navigation />
<Hero />
{/* Esta parte es renderizada bajo demanda */}
<Suspense fallback={<ProductSkeleton />}>
<ProductRecommendations />
</Suspense>
{/* Estático nuevamente */}
<Footer />
</>
);
}Performance Tracks
Nueva herramienta para profiling detallado de performance.
Integración con DevTools
import { startTrack, endTrack } from 'react';
function ExpensiveComponent() {
startTrack('ExpensiveComponent:render');
const result = expensiveCalculation();
endTrack('ExpensiveComponent:render');
return <div>{result}</div>;
}Visualización en React DevTools
El Profiler ahora muestra:
- Tiempo de renderización por track
- Cascada de dependencias
- Impacto de Server Components vs Client Components
- Métricas de cache hit/miss
Mejoras del React Compiler
El React Compiler introducido en React 19 recibió mejoras significativas.
Memoización Automática Mejorada
// React Compiler ahora optimiza automáticamente
function ProductCard({ product, onAddToCart }) {
// Antes: Necesitaba useMemo/useCallback
// Ahora: Compiler optimiza automáticamente
const formattedPrice = formatCurrency(product.price);
const handleClick = () => onAddToCart(product.id);
return (
<div onClick={handleClick}>
<h3>{product.name}</h3>
<p>{formattedPrice}</p>
</div>
);
}
Migración Para React 19.2
Actualizando Dependencias
npm install react@19.2.0 react-dom@19.2.0Verificando Compatibilidad
// Verificar versión
import { version } from 'react';
console.log(version); // "19.2.0"
// Verificar si Activity está disponible
const hasActivity = typeof Activity !== 'undefined';Habilitando Nuevas Features
// next.config.js (para Next.js)
module.exports = {
experimental: {
ppr: true, // Partial Pre-rendering
reactCompiler: true,
},
};Comparación de Versiones
| Feature | React 19 | React 19.1 | React 19.2 |
|---|---|---|---|
| Server Components | Estable | Estable | Estable |
| Actions API | Nuevo | Mejorado | Mejorado |
| use() API | Nuevo | Estable | Estable |
| Compiler | Beta | Estable | Mejorado |
| Activity | - | - | Nuevo |
| useEffectEvent | - | - | Nuevo |
| Partial Pre-rendering | - | Experimental | Estable |
Mejores Prácticas
Cuándo Usar Activity
// BUENO: Tabs con estado complejo
<Activity mode={activeTab === 'editor' ? 'visible' : 'hidden'}>
<CodeEditor />
</Activity>
// BUENO: Modales que preservan estado
<Activity mode={isModalOpen ? 'visible' : 'hidden'}>
<Modal>
<ComplexForm />
</Modal>
</Activity>
// EVITAR: Contenido simple sin estado
// Usa renderización condicional normal
{showContent && <SimpleContent />}Cuándo Usar useEffectEvent
// BUENO: Callbacks en effects de larga duración
const handleMessage = useEffectEvent(onMessage);
// BUENO: Analytics y logging
const logEvent = useEffectEvent((event) => analytics.log(event));
// EVITAR: Sustituir useCallback para handlers de eventos normales
// useCallback aún es apropiado para props de componentes
Conclusión
React 19.2 continúa la evolución de React hacia una arquitectura más eficiente y flexible. Activity y useEffectEvent resuelven problemas reales de desarrollo, mientras Partial Pre-rendering ofrece ganancias significativas de performance.
La recomendación es comenzar experimentando estas features en proyectos nuevos o partes aisladas de proyectos existentes antes de una migración completa.
Si quieres profundizar tus conocimientos en React y JavaScript moderno, recomiendo que revises otro artículo: ECMAScript 2025: Todas las Nuevas Features donde vas a descubrir las novedades de JavaScript que complementan React 19.2.
¡Vamos a por ello! 🦅
🎯 Únete a los Desarrolladores que Están Evolucionando
Miles de desarrolladores ya usan nuestro material para acelerar sus estudios y conquistar mejores posiciones en el mercado.
¿Por qué invertir en conocimiento estructurado?
Aprender de forma organizada y con ejemplos prácticos hace toda la diferencia en tu jornada como desarrollador.
Comienza ahora:
- 1x de R$9,90 en tarjeta
- o R$9,90 al contado
"Material excelente para quien quiere profundizarse!" - João, Desarrollador

