Capítulo 65 de 116

Chapter 65: useTransition

Core Idea

useTransition() marks a state update as a low-priority "transition," letting React keep the current UI responsive (and interruptible by more urgent updates like typing) while the transition's render work happens in the background, plus it defines what an "Action" is throughout the rest of the Hooks in this reference section.

Key Concepts

  • Signature: const [isPending, startTransition] = useTransition(). Wrap a state update in startTransition(() => setState(...)) to mark it non-urgent; isPending is true while that transition's render work is still in progress.
  • Urgent vs. transition updates: direct user input (typing in a field, pressing a key) should update state immediately/urgently outside a transition; a resulting expensive re-render (e.g. re-filtering a large list based on that input) is a good candidate to wrap in startTransition so it doesn't block the input from feeling instant.
  • Interruptible: if a new urgent update arrives while a transition is still rendering, React abandons the in-progress transition render and restarts with the latest state — transitions never block more important work.
  • What "Actions" means: functions called inside startTransition (including async functions passed to a form's action prop) are called Actions throughout the rest of this reference — useActionState and useOptimistic are both built around this same underlying mechanism, supporting async functions directly (a transition can await work and keep isPending true until it resolves).
  • Not a replacement for useDeferredValue: useTransition marks the state update itself as low priority (you control the setState call); useDeferredValue (Ch 52) instead lets a received value lag behind, useful when you don't control where the state update originates (e.g. a value coming from a parent prop).

Code Examples

const [isPending, startTransition] = useTransition();

function selectTab(nextTab) {
  startTransition(() => {
    setTab(nextTab); // expensive re-render of tab content, marked low-priority
  });
}
  • What it demonstrates: a tab switch's state update wrapped so its (potentially expensive) re-render doesn't block the click itself from feeling instant, with isPending available to show a loading indicator.

Key Takeaways

  1. Wrap the state update in startTransition when you own the setState call and want its render work deprioritized; use useDeferredValue instead when you only receive a value, not the update that produced it.
  2. Transitions are interruptible by design — a fresher urgent update always wins over an in-progress transition render.
  3. "Action" is the term used throughout useActionState/useOptimistic/form action for exactly this transition-wrapped-function concept — understanding this Hook first makes those others click faster.

Connects To

  • Ch 48 (useActionState) and Ch 60 (useOptimistic): both built on the Actions concept defined here.
  • Ch 52 (useDeferredValue): the related tool for a received (not self-triggered) value.