Learn / Frameworks / React / Transitions, Deferred Values and useId

React · Lesson 10 of 15

Transitions, Deferred Values and useId

Keep the UI responsive with concurrent features and stable ids.

  • Intermediate
  • 15 min read
  • 3 objectives

Before this lessonLesson 9: Performance: memo, useMemo and useCallback

What you will learn

  • Mark an update as a transition
  • Defer a heavy value
  • Generate stable ids

Your Progress

0 of 15 lessons 0%

  • Lessons0 / 15
  • Completed0
  • Est. time left~ 4 hours

Create a free account to keep your progress on every device.

Some updates must feel instant (typing in a box). Others can wait (filtering a big list). Concurrent React lets you mark the slow work as a transition so the input stays snappy.

useTransition

import { useState, useTransition } from "react";

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

  function onChange(e) {
    const q = e.target.value;
    setQuery(q);                              // urgent: the input
    startTransition(() => {
      setList(items.filter((i) => i.includes(q)));   // can wait
    });
  }

  return (
    <>
      <input value={query} onChange={onChange} />
      {pending && <p>Updating…</p>}
      <ul>{list.map((i) => <li key={i}>{i}</li>)}</ul>
    </>
  );
}

useDeferredValue

When you cannot wrap the setter (a library owns it), defer the value instead. React keeps showing the previous value until the new one is ready.

const deferredQuery = useDeferredValue(query);
const visible = items.filter((i) => i.includes(deferredQuery));

useId for labels

Server and client must generate the same id, or hydration mismatches. useId is built for that.

function Field({ label }) {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </>
  );
}
Up next · Lesson 11Suspense and Error BoundariesShow fallbacks while data loads and recover when a subtree throws.