# useTransition: non-urgent updates

useTransition marks an update as non-urgent: the input stays responsive and isPending tells you when the work is still running.

> Page: https://ui.eneawork.it/blog/react-transition-usi
> Markdown: https://ui.eneawork.it/blog/react-transition-usi.md

*2026-11-01*

useTransition separa due aggiornamenti di stato: quello urgente, che deve seguire la digitazione, e quello non urgente, che può aspettare. startTransition avvolge il secondo e isPending dice quando è ancora in corso.

Il catalogo EneUI conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, misurati da /api/stats il 1 novembre 2026. La cifra viene da una query all'endpoint, non da una stima: conta i record pubblicati, non la qualità dei componenti.

## Cosa cambia per l'utente

L'input controllato si aggiorna subito, la lista filtrata arriva dopo. React interrompe il render non urgente se arriva un tasto nuovo, quindi il campo non perde caratteri mentre il filtro lavora.

## Il caso eseguibile

import { useState, useTransition } from "react"; export function Ricerca({ righe }) { const [testo, setTesto] = useState(""); const [filtro, setFiltro] = useState(""); const [inCorso, startTransition] = useTransition(); function cambia(e) { const valore = e.target.value; setTesto(valore); startTransition(() => setFiltro(valore)); } const visibili = righe.filter((r) => r.includes(filtro)); return ( {visibili.map((r) => ( {r} ))} ); }

Nel codice il valore dell'input è urgente, il filtro è non urgente. Con diecimila righe la differenza si sente; con venti no, ed è il momento di togliere la transizione e lasciare due setState normali.

## Azioni asincrone

In React 19 startTransition accetta una funzione asincrona: isPending resta vero fino all'await finale. Così un form mostra lo stato di invio senza un booleano in più, e il risultato entra in una transizione sola.

## Record vivi nel catalogo

La categoria search raccoglie i campi di ricerca del catalogo, con un command menu che filtra mentre digiti; per l'attesa breve c'è lo spinner di Kibo UI, licenza MIT.

## La limitazione

Una transizione non rende veloce il lavoro: sposta il costo dopo l'input e lo rende interrompibile. Se la lista non è memoizzata, React rifà comunque il render e il guadagno sparisce; inoltre isPending è un booleano, non una percentuale.

## Dove continuare

Le novità della versione sono in React 19, cosa cambia; l'attesa con fallback è in Suspense: cosa sospende; lo streaming lato server è in streaming e Suspense in Next.js. Il confronto fra React e Svelte è in Svelte vs React.

## FAQ

### useTransition e useDeferredValue sono la stessa cosa?

No. useTransition decide quando parte un aggiornamento che controlli tu; useDeferredValue parte da un valore esistente e non richiede di cambiare il setter.

### La transizione evita il lavoro pesante?

No, lo rende interrompibile e lo sposta dopo l'input. Il render non urgente avviene comunque, quindi il costo totale resta lo stesso.

### Perché isPending resta falso?

Perché l'aggiornamento è finito in meno di un frame, oppure perché startTransition è stato chiamato fuori da un evento o da un effetto. Con una lista piccola è il comportamento atteso.

### Posso usare startTransition per il valore dell'input?

No, il valore dell'input deve restare urgente. Se lo metti in transizione il campo si svuota o perde caratteri mentre React rimanda il render.

### Funziona anche senza React 19?

Sì, useTransition esiste dalla 18. La forma con funzione asincrona e le azioni richiedono la 19.
