PAS7 Studio

Tecnologia

React nel 2026: i nuovi primitivi (Actions, Activity, useEffectEvent) e l’era del Compiler

React 19 → 19.2 non ha solo aggiunto feature: ha cambiato il modo in cui strutturiamo le app. Questa guida spiega le idee dietro Actions, <Activity/>, useEffectEvent, Performance Tracks, batching di Suspense in SSR, Partial Pre-rendering e React Compiler 1.0 — con segnali architetturali pratici e fonti reali.

17 feb 2026· 18 min di lettura
Metafora taccuino: primitivi React e l’era del compiler — componenti disegnati a mano, frecce async e note di performance

Cosa ti porterai a casa da questo articolo

Non è un dump di changelog. È un modello mentale: cosa è cambiato, perché esiste e come influisce sull’architettura.

  • Il “perché” dietro i nuovi primitivi di React (meno colla, più pattern ufficiali). [1][2][3]

  • Quando Actions, <Activity/> e useEffectEvent sono lo strumento giusto (e quando no). [1][2][6][8]

  • Come Performance Tracks cambia il debugging e le conversazioni sulla performance. [2][5]

  • Cosa cambia in React 19.2 nello streaming SSR con Suspense (batching). [2]

  • Come React Compiler 1.0 cambia la storia della memoization (senza magia). [3]

  • Una roadmap di deep-dive che pubblicheremo per ogni concetto (con codice e pattern reali). [1][2][3]

Il vero cambio: React sta trasformando i pattern “folklore” in primitivi

React era un po’ come LEGO senza istruzioni: potevi costruire qualsiasi cosa, ma ogni team inventava il proprio “modo giusto” per gestire mutation async, mantenere lo state tra schermate o evitare bug nelle dipendenze degli effect.

React 19 e 19.2 suonano diversi. Il team sta trasformando quei pattern ricorrenti in primitivi: Actions per lo stato async UI, <Activity/> per “nascondi ma mantieni lo state”, useEffectEvent per separare logica “event-like” dagli effect e Performance Tracks ufficiali per capire lo scheduling. [1][2][5]

E poi c’è React Compiler 1.0: una scommessa forte sul fatto che la memoization manuale non dovrebbe essere un lavoro quotidiano. [3]

Actions: rendere i flussi async dell’UI noiosi (nel senso buono)

Se la tua UI fa mutation (salva profilo, checkout, commento, upload), probabilmente hai già costruito questo state machine mille volte: idle → pending → success/error → UI ottimistica → rollback → toast → redirect.

La direzione Actions di React 19 prova a standardizzare quel flusso con primitivi come useActionState, <form action={...}> e useFormStatus, e a rendere gli update ottimistici meno scomodi con useOptimistic. [1][8]

Ecco un esempio piccolo che mostra la forma dell’approccio:

TSX
import { useActionState } from "react";

type SaveState = { ok: true } | { ok: false; error: string };

async function saveDisplayName(
  _prev: SaveState,
  formData: FormData,
): Promise<SaveState> {
  const name = String(formData.get("name") ?? "").trim();
  if (name.length < 2) return { ok: false, error: "Name is too short." };

  const res = await fetch("/api/profile/name", {
    method: "POST",
    body: JSON.stringify({ name }),
    headers: { "content-type": "application/json" },
  });

  if (!res.ok) return { ok: false, error: "Failed to save." };
  return { ok: true };
}

export function DisplayNameForm({ initialName }: { initialName: string }) {
  const [state, action, isPending] = useActionState<SaveState, FormData>(
    saveDisplayName,
    { ok: true },
  );

  return (
    <form action={action} className="space-y-2">
      <input name="name" defaultValue={initialName} />
      <button type="submit" disabled={isPending}>
        {isPending ? "Saving…" : "Save"}
      </button>
      {state.ok ? null : <p role="alert">{state.error}</p>}
    </form>
  );
}

Segnale architetturale: Actions è ottimo quando il flusso di mutation è “di proprietà” della UI e vuoi un handshake standard pending/risultato senza inventare un altro layer di astrazione. Se ti servono caching, retry, code offline o sincronizzazione cross-screen, spesso è meglio un data layer (React Query, SWR, event bus custom). Actions riduce il boilerplate ai bordi: non sostituisce l’architettura dati a livello di sistema. [1][8]

<Activity />: “nascondi” diventa un concetto di prima classe

UI a tab, pannelli laterali, wizard e flow multi-step hanno un trade-off classico:

- smontare (unmount) quando nascosto → meno memoria, ma perdi state e teardown di subscription

- mantenere montato → preservi state, ma finisci per reinventare pattern “nascosto ma vivo”

React 19.2 introduce <Activity mode="visible|hidden"> come alternativa al rendering condizionale. In 19.2 supporta visible e hidden. [2]

Un esempio micro per un tab “keep alive”:

TSX
import { Activity } from "react";

export function SettingsTabs({ tab }: { tab: "profile" | "billing" }) {
  return (
    <div>
      <Activity mode={tab === "profile" ? "visible" : "hidden"}>
        <ProfileTab />
      </Activity>
      <Activity mode={tab === "billing" ? "visible" : "hidden"}>
        <BillingTab />
      </Activity>
    </div>
  );
}

Segnale architetturale: usa <Activity/> quando vuoi retention dello state prevedibile durante i toggle di visibilità (tab, drawer, shell di navigazione). <Activity/> rende esplicita l’intenzione; non ferma automaticamente timer/subscription costosi dentro la UI nascosta — devi comunque progettare dove vive quel lavoro. [2]

useEffectEvent: smetti di riconnetterti perché è cambiato il tema

Gli effect hanno una tensione nota: vuoi dependency array corretti, ma a volte vuoi anche “questo handler deve vedere i valori più recenti senza forzare un re-run dell’effect”.

In React 19.2, useEffectEvent formalizza quel pattern. Nel post React 19.2 c’è l’esempio chat: cambiare theme non dovrebbe riconnettere la chat, ma la notifica dovrebbe usare l’ultimo theme. useEffectEvent sposta la logica “event-like” fuori dall’effect. [2][6]

Un esempio pratico (analytics/logging) che resta amico del linter:

TSX
import { useEffect, useEffectEvent } from "react";

type Props = { userId: string; plan: "free" | "pro" };

declare function subscribeToBillingEvents(
  userId: string,
  onEvent: (name: string) => void,
): () => void;

declare function track(event: string, props: Record<string, string>): void;

export function BillingWatcher({ userId, plan }: Props) {
  const onBillingEvent = useEffectEvent((name: string) => {
    track("billing_event", { name, plan });
  });

  useEffect(() => {
    return subscribeToBillingEvents(userId, (name) => onBillingEvent(name));
  }, [userId]);

  return null;
}

Segnale architetturale: useEffectEvent è un grande win quando oggi sopprimi il hooks linter solo per evitare che un effect si riesegua. Ma non impacchettare tutto: React avverte esplicitamente di non usarlo solo per zittire il linter. Usalo quando la logica è concettualmente un evento, non parte del “sincronizza questo sistema” reattivo. [2][6]

Performance Tracks: lo scheduling di React diventa visibile (e debuggabile)

Prima, il debugging delle performance era spesso un gioco d’ipotesi: “perché questo update è lento?”. Performance Tracks rende il lavoro di React chiaro nella timeline.

Performance Tracks non rende le app più veloci per magia. Rende il lavoro sulle performance più onesto: smetti di ottimizzare “a sensazione” e inizi a ottimizzare con evidenza. [5]

Perché conta

meno ipotesi

Invece di dire “React è lento”, vedi cosa ha fatto React e quando — soprattutto intorno alle interazioni e allo scheduling. [5]

Dove aiuta di più

jank nelle interazioni

Perfetto per capire click lenti, input lag, reveal di suspense e commit lunghi, perché il lavoro è etichettato nella timeline. [5]

Effetto sull’architettura

confini migliori

I team tendono a costruire boundary più puliti (transitions, suspense, flussi async) quando possono misurare l’impatto direttamente. [2][5]

Performance Tracks in azione: il lavoro di React appare come track dedicati nella timeline Performance. [2][5]

Section performance-tracks screenshot

Overview: la timeline separa Scheduler, Components e fasi chiave (blocking, transitions, suspense). [5]

Section performance-tracks screenshot

Scheduler track: puoi vedere timing degli eventi e fasi come update, render, commit e waiting for paint. [5]

Section performance-tracks screenshot

Close-up: utile per capire quale fase domina una interazione lenta. [5]

Section performance-tracks screenshot

SSR in React 19.2: batching dei reveal di Suspense riduce il “caos progressivo”

React 19.2 cambia come si rivelano i boundary Suspense renderizzati dal server: boundary che finiscono nello stesso momento possono essere batchati. L’obiettivo è allineare meglio lo streaming SSR con il rendering client e ridurre reveal strani e troppo frammentati. [2]

È un buon esempio della direzione 2026 di React: rendere il reveal più prevedibile e meno dipendente da “incidenti di timing”. [2]

Effetto lato utente

reveal più puliti

Meno “appare un pezzo, poi un altro, poi un altro” quando i boundary completano nello stesso momento. [2]

Effetto lato dev

meno sorprese

Lo streaming SSR diventa più vicino al comportamento del client, semplificando modelli mentali e debugging. [2]

Segnale architetturale

progetta i boundary

I boundary Suspense fanno parte del design UX. Raggruppa ciò che deve apparire insieme, separa ciò che può arrivare dopo. [2]

Prima: i boundary Suspense SSR possono rivelarsi in step più piccoli e irregolari. [2]

Section ssr-suspense-batching screenshot

Dopo: boundary correlati che completano insieme possono rivelarsi come un singolo batch, con una progressione più pulita. [2]

Section ssr-suspense-batching screenshot

React Compiler 1.0: la memoization passa dal code review al build time

React Compiler 1.0 è stabile e pronto per produzione. È uno strumento build-time che ottimizza componenti e hook con memoization automatica, e porta regole lint “compiler-powered” tramite preset di eslint-plugin-react-hooks. [3]

L’idea non è “React è lento se non compili”. È: la memoization manuale è fragile, incoerente tra team e spesso diventa useMemo/useCallback sparsi ovunque per abitudine.

La guida di React è pragmatica: affidati al compiler di default, tieni useMemo/useCallback come escape hatch quando serve controllo preciso (spesso sulle dipendenze degli effect). E testa bene prima di rimuovere memoization esistente, perché può cambiare l’output della compilazione. [3]

Un esempio minimo di cosa cambia a livello architetturale (meno ottimizzazioni manuali):

TSX
type Props = { items: Array<{ id: string; price: number }>; taxRate: number };

declare function expensiveTotal(items: Props["items"], taxRate: number): number;

declare function CheckoutSummary(props: { total: number }): JSX.Element;

export function Cart({ items, taxRate }: Props) {
  const total = expensiveTotal(items, taxRate);
  return <CheckoutSummary total={total} />;
}

Con un compiler puoi spesso mantenere il codice dichiarativo e lasciare allo strumento decidere cosa è sicuro memoizzare — purché rispetti le Rules of React e testi correttamente. [3]

Partial Pre-rendering: una leva nuova per “shell statica + riempimento dinamico”

Partial Pre-rendering (React DOM, 19.2) è l’idea di pre-renderizzare parti statiche in anticipo (ottimo per CDN), poi riprendere più tardi per riempire i contenuti dinamici. Nel post React 19.2 c’è il flow prerender() → salva stato postponed → resume(). [2]

Segnale architetturale: se hai un sito content-heavy dove la shell è per lo più statica ma personalizzazione/dati sono dinamici, PPR è potente. Il trade-off è operativo: non è “solo React”, è una pipeline di rendering e una scelta di integrazione framework/bundler. [2]

React Server Components: stabile, ma tratta l’ecosistema come un sistema

React Server Components (RSC) sono stabili a livello React in React 19, ma i docs avvertono esplicitamente che le API sottostanti usate da bundler/framework possono rompersi tra minor 19.x e non seguono semver. Per gli implementer, l’approccio consigliato è pinning a una versione specifica di React o usare Canary. [4]

Inoltre: segui le security advisory. Il team React ha pubblicato vulnerabilità RSC che impattano react-server-dom-* e ha raccomandato l’upgrade a versioni fixate. [7]

Segnale architetturale: se usi RSC, tratta versione React, integrazione framework/bundler e pacchetti react-server-dom-* come un’unica unità di upgrade, con disciplina sulle patch.

Roadmap serie: deep dive successivi (con codice e pattern reali)

Questo post è l’overview. Poi andiamo in profondità — un concetto alla volta — con esempi reali e trade-off architetturali.

  • Actions in app reali: form, UI ottimistica, shaping degli errori e integrazione con React Query/SWR. [1][8]

  • <Activity/> nella pratica: tab shell, drawer, pattern “route-like” e come evitare leak in subtree nascosti. [2]

  • Pattern useEffectEvent: analytics, subscription, real-time sockets e design degli effect compatibile col linter. [2][6]

  • Playbook Performance Tracks: cosa guardare, pattern comuni e come interpretare le fasi in app reali. [5]

  • Design dei boundary Suspense in SSR: implicazioni del batching e architetture che producono reveal puliti. [2]

  • Adozione React Compiler: rollout incrementale, strategia di test e quando tenere memoization manuale. [3]

  • Architettura Partial Pre-rendering: cosa pre-renderizzare, dove riprendere e implicazioni CDN/edge. [2]

  • Checklist hardening RSC: pinning, patch cadence e playbook di risposta alle advisory. [4][7]

Fonti

Includiamo solo fonti che supportano direttamente affermazioni ed esempi usati in questo articolo.

FAQ

Dovremmo aggiornare subito a React 19.2?

Se sei già su React 19, 19.2 è un upgrade pratico per i nuovi primitivi e i miglioramenti ai devtools. Se usi React Server Components, segui anche le security advisory del team React e assicurati di aggiornare i pacchetti impattati alle versioni fixate. [2][7]

Actions sostituisce React Query / SWR?

No. Actions riduce il boilerplate lato UI per mutation e form. Le data library restano forti per caching, retry, refresh in background, offline e consistenza cross-screen. In molte app li userai insieme in modo intenzionale. [1][8]

Qual è il vero vantaggio di useEffectEvent?

Ti aiuta a mantenere corrette le dipendenze degli effect senza riconnettere/rieseguire un effect solo perché un handler deve vedere i valori più recenti. È particolarmente utile se oggi disabiliti il hooks linter per evitare re-run. [2][6]

<Activity/> è solo “keep mounted”?

Concettualmente sì, ma la parte importante è rendere esplicita l’intenzione e dare a React un primitivo corretto per UI “nascosta ma viva”. Questa chiarezza aiuta l’architettura e apre la porta a futuri miglioramenti di scheduling/prioritizzazione. [2]

React Compiler significa che possiamo eliminare tutti i useMemo/useCallback?

Non automaticamente. La guida React è: affidati al compiler di default, tieni i memo hook come escape hatch quando serve controllo preciso (spesso sulle dipendenze degli effect). E testa con attenzione prima di rimuovere memoization esistente. [3]

React Server Components è sicuro e stabile ora?

RSC è stabile a livello React in React 19, ma l’integrazione ecosistema (bundler/framework) è una questione di sistema. Segui le indicazioni di pinning dove serve e monitora le security advisory per i pacchetti `react-server-dom-*`. [4][7]

Vuoi aiuto per fare upgrade senza regressioni?

I nuovi primitivi di React sono potenti — ma adottarli in sicurezza richiede igiene ingegneristica: test, lint e un piano architetturale chiaro.

Se stai pianificando un upgrade React (o vuoi adottare Compiler/Actions/RSC senza rompere la produzione), PAS7 Studio può aiutare con un approccio audit-first e un rollout su misura per il tuo stack.

Articoli correlati

Scopri altri articoli utili

growthFebruary 15, 2026

AI SEO / GEO nel 2026: i tuoi prossimi clienti non sono umani — sono agenti

La ricerca sta passando dai click alle risposte. Bot e agenti AI scansionano, citano, raccomandano e sempre più spesso acquistano. Scopri cosa significa AI SEO / GEO, perché la SEO classica non basta più e come PAS7 Studio aiuta i brand a vincere visibilità nel web “agentico”.

Leggere →
telegram-media-saverJanuary 8, 2025

Tag automatici e ricerca per link salvati

Integra con GDrive/S3/Notion per tag automatici e ricerca veloce tramite API di ricerca

Leggere →
servicesJanuary 1, 2025

Sviluppo di bot e servizi di automazione

Sviluppo professionale di bot Telegram e automazione dei processi aziendali: chatbot, assistenti AI, integrazioni CRM, automazione dei flussi di lavoro.

Leggere →
backend-engineeringFebruary 15, 2026

Bun vs Node.js nel 2026: perché Bun sembra più veloce (e come valutare l’app prima di migrare)

Bun è un toolkit JavaScript all-in-one più rapido: runtime, package manager, bundler e test runner. Qui trovi cosa è reale (con benchmark), cosa può rompersi e come ottenere un audit di readiness gratuito con @pas7-studio/bun-ready.

Leggere →

Sviluppo professionale per la tua attività

Creiamo soluzioni web moderne e bot per le aziende. Scopri come possiamo aiutarti a raggiungere i tuoi obiettivi.