Torna al blog

React 19.2: Novità e Miglioramenti - Release Ottobre 2025

Scopri React 19.2: Activity Component, useEffectEvent Hook, cacheSignal, Performance Tracks, Partial Pre-rendering e tutte le novità di ottobre 2025.

Edoardo Midali

Edoardo Midali

Developer · Content Creator

4 min di lettura
React 19.2: Novità e Miglioramenti - Release Ottobre 2025

React 19.2 è stato rilasciato il 1 ottobre 2025. Questa release introduce <Activity /> per UI nascosta con state preservation, useEffectEvent Hook per Effects non-reattivi, cacheSignal per RSC cache lifetime, Performance Tracks nei DevTools e Partial Pre-rendering per SSR avanzato.

🎯 Novità Principali

<Activity /> Component

Nascondi UI preservando state ed effects!

// ❌ Prima - unmount completo
{
  isVisible && <Page />;
}

// ✅ React 19.2 - Activity
<Activity mode={isVisible ? "visible" : "hidden"}>
  <Page />
</Activity>;

Modes:

  • visible: UI mostrata, effects attivi, updates normali
  • hidden: UI nascosta, effects unmounted, updates deferred

Use case - Tab navigation:

function App() {
  const [activeTab, setActiveTab] = useState("home");

  return (
    <>
      <Tabs onChange={setActiveTab} />

      {/* ✅ Tabs preserve state when hidden! */}
      <Activity mode={activeTab === "home" ? "visible" : "hidden"}>
        <HomeTab />
      </Activity>

      <Activity mode={activeTab === "profile" ? "visible" : "hidden"}>
        <ProfileTab />
      </Activity>
    </>
  );
}

Vantaggi:

  • State preservation: No perdita input/scroll
  • Background loading: Preload next navigation
  • Performance: Hidden = no paint/layout

useEffectEvent Hook

Extract non-reactive logic da Effects!

// ❌ Problem - Effect re-runs on message change
function Chat({ roomId, message }) {
  useEffect(() => {
    const connection = createConnection(roomId);
    connection.on("connected", () => {
      showNotification("Connected!");
      sendAnalytics(message); // ❌ message cambia → re-connect!
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, message]); // ❌ message in deps
}

// ✅ Solution - useEffectEvent
function Chat({ roomId, message }) {
  const onConnected = useEffectEvent(() => {
    showNotification("Connected!");
    sendAnalytics(message); // ✅ Usa latest message senza deps!
  });

  useEffect(() => {
    const connection = createConnection(roomId);
    connection.on("connected", onConnected);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]); // ✅ Solo roomId in deps!
}

Vantaggi:

  • No re-runs: Effect stabile
  • Latest values: Accesso a props/state fresh
  • Cleaner: Meno dependency hell

cacheSignal (RSC)

Know when cache() lifetime ends:

import { cache, cacheSignal } from "react";

const getUserData = cache(async (userId) => {
  const abort = cacheSignal();

  const data = await fetch(`/api/users/${userId}`, { signal: abort });
  return data.json();
});

// ✅ Fetch cancelled quando cache expires

Performance Tracks

React performance nei Browser DevTools!

// React 19.2 aggiunge track "React" in:
// Chrome DevTools → Performance → Timeline

// Vedi:
// - Component render times
// - Suspense boundaries
// - State updates
// - Effects execution

Screenshot DevTools:

Timeline:
├─ Main
├─ GPU
└─ React ← ✨ New!
   ├─ <App> render (2.3ms)
   ├─ <List> render (5.1ms)
   └─ useEffect (1.2ms)

Partial Pre-rendering

Pre-render shell + resume dinamico!

// Step 1: Pre-render
const { prelude, postponed } = await prerender(<App />, {
  signal: abortController.signal,
});

// Step 2: Serve prelude (static shell)
res.write(prelude);

// Step 3: Resume con dynamic content
const postponedState = await getPostponedState(request);
const resumeStream = await resume(<App />, postponedState);

// Stream dynamic parts
resumeStream.pipe(res);

Use case:

// App con mixed rendering
function App() {
  return (
    <>
      <StaticHeader /> {/* Pre-rendered */}
      <Suspense fallback={<Loading />}>
        <DynamicFeed /> {/* Resumed later */}
      </Suspense>
    </>
  );
}

📊 Other Changes

Batching Suspense Boundaries

// ✅ Suspense reveals now batched (smooth animations)
<Suspense fallback={<Loading />}>
  <SlowComponent />
</Suspense>

SSR Web Streams (Node.js)

// ✅ Node.js ora supporta Web Streams
const stream = await renderToReadableStream(<App />);

eslint-plugin-react-hooks v6

npm install eslint-plugin-react-hooks@6
# ✅ Supporta useEffectEvent
# ✅ Activity validations

useId Prefix Update

// ❌ Prima: :r:1, :r:2
// ✅ 19.2: _r_1, _r_2

// Why: Valid per view-transition-name CSS!

🔄 Migration

npm install react@19.2 react-dom@19.2

# TypeScript
npm install @types/react@19.2 @types/react-dom@19.2

💡 Conclusioni

React 19.2 introduce:

<Activity /> - State preservation per hidden UI ✅ useEffectEvent - Effects più stabili ✅ Performance Tracks - Profiling migliorato ✅ Partial Pre-rendering - SSR avanzato ✅ Backward compatible - Drop-in upgrade