Code Reference

useTransition

React · Reference cheat sheet

useTransition

React · Reference cheat sheet


📋 Overview

useTransition marks state updates as non-urgent so React can keep the UI responsive. Returns [isPending, startTransition]. Use for heavy re-renders (filtering large lists, tab switches) while keeping input snappy.

🔧 Core concepts

  • Urgent vs transition — typing stays urgent; list filter can be a transition.
  • startTransition(fn) — wrap the setState that triggers expensive UI.
  • isPending — true while the transition is in progress.
  • useDeferredValue — alternative when you defer a value instead of an update.
  • Concurrent — requires concurrent features (React 18+).

💡 Examples

import { useState, useTransition } from "react";

export function Search({ items }: { items: string[] }) {
  const [query, setQuery] = useState("");
  const [list, setList] = useState(items);
  const [isPending, startTransition] = useTransition();

  function onChange(e: React.ChangeEvent<HTMLInputElement>) {
    const value = e.target.value;
    setQuery(value); // urgent: update input
    startTransition(() => {
      setList(items.filter((item) => item.includes(value)));
    });
  }

  return (
    <div>
      <input value={query} onChange={onChange} />
      {isPending ? <p>Updating…</p> : null}
      <ul>
        {list.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

Navigation-style:

startTransition(() => setTab("photos"));

⚠️ Pitfalls

  • Wrapping controlled input updates in startTransition → laggy typing.
  • Side effects inside transitions that assume immediate commit.
  • Expecting transitions to cancel fetches—pair with AbortController / effects carefully.
  • Nested transitions without understanding pending boundaries.

On this page