Engrain by ByteRush

RCT.02.03 Senior· 12 minCore — asked often

Concurrent rendering: transitions, deferred values and tearing

Keep input responsive while a slow part of the UI updates: urgent vs transition updates, useTransition and startTransition, useDeferredValue, isPending, interrupted renders, and how useSyncExternalStore prevents tearing.

Comes up in: React, Frontend system design

Learn#

Ishita’s product search filters 5,000 items on every keystroke. Typing lags by half a second, because each letter waits for the whole list to render.

Concurrent rendering lets React prepare a render in the background and interrupt it. You mark which updates can wait. Urgent updates, such as typing, clicking and pressing, render at once. A transition is a non-urgent update that can be interrupted.

const [isPending, startTransition] = useTransition();
function onTabClick(tab) {
  startTransition(() => setTab(tab)); // can be interrupted
}

When you do not own the state update, such as a prop, use a deferred value: const deferredQuery = useDeferredValue(query). The input uses query; the slow list uses deferredQuery, which lags behind.

Typing stays fast while the list catches upStep 1 of 4

Page

  • <input value="s">

State

    empty

    The user types "s". setQuery('s') is urgent: the input re-renders at once.

    Read the steps as text
    1. The user types "s". setQuery('s') is urgent: the input re-renders at once.
    2. The filtered list uses useDeferredValue(query). React starts a background render of 5,000 rows for "s".
    3. The user types "h" before it finishes. React drops the unfinished "s" render and handles the keystroke first.
    4. With typing paused, the "sh" list render completes and commits. Meanwhile the old list stayed visible, dimmed with isPending.

    Predict#

    Predict first

    You wrap setQuery (bound to a controlled input) in startTransition. What happens when the user types?

    Interview angle#

    Say it like this — about 30 seconds

    “Transitions mark updates as non-urgent. With useTransition or startTransition, React renders them in the background, interrupts them for urgent input, and throws away renders that are already stale. isPending lets me show the old UI dimmed instead of a spinner. useDeferredValue does the same for a value I receive. Tearing is when parts of the UI show different versions of external state during a concurrent render; useSyncExternalStore prevents it by reading a consistent snapshot.”

    Stays on your device. Nothing is uploaded.
    Follow-up What are transitions in React? When would you use useTransition?
    Non-urgent updates React can interrupt; use them for tab switches, filtering big lists or navigation, keeping input responsive.
    Follow-up What is tearing, and how does useSyncExternalStore prevent it?
    Tearing is different components showing different values of the same external store in one render; useSyncExternalStore reads one snapshot and forces a synchronous re-render if it changes.
    Follow-up Does a transition make the slow render faster?
    No. It only keeps the UI responsive while it runs; make the render itself cheaper with memoization or virtualization.

    Practice#

    On your own

    Build a small external store that works correctly with useSyncExternalStore.

    Done when

    • getSnapshot returns the same object until the state changes.
    • Subscribers are notified after each real change, and can unsubscribe.
    • Updates that return the same object do nothing.
    Your solution
    Ctrl/⌘ + Enter

    Remember#

    Try to answer each card before you open it. Then add them to your reviews.

    What does startTransition do?

    Marks updates as non-urgent so React can interrupt them for urgent input.

    When do you use useDeferredValue instead of useTransition?

    When you get the value as a prop and do not own the state update.

    What is tearing?

    Parts of the UI showing different versions of the same external state.

    Why must getSnapshot return a cached object?

    A new object each call looks like a change, so React re-renders forever.

    Go deeper

    Four layers. Stop at the one your interview needs; each ends with a quick check.

    The core ideaEvery round
    isPending is true while a transition renders. Show the old content with lower opacity instead of a spinner, so the page does not jump.
    Check yourself: What does isPending tell you?

    A transition is still rendering in the background.

    How it works underneathSenior rounds
    Transition renders run in small slices (RCT.02.02). If newer input arrives, React abandons the half-finished render and starts again with the latest state, so only the final result commits Source: React: useTransition.
    Check yourself: What happens to a transition render that becomes outdated?

    React throws it away and starts again with the latest state.

    Edge cases and trapsWhere people slip

    Tearing happens when a store changes between slices of one render. useSyncExternalStore(subscribe, getSnapshot) detects that and re-renders synchronously with one consistent snapshot Source: React: useSyncExternalStore.
    State libraries such as Zustand use it inside.

    Check yourself: Why did external stores tear in concurrent rendering?

    The store could change between slices of a render, so components read different values.

    In productionStaff-level answers

    Use transitions for navigation, tabs and heavy filtering; routers in React 19 frameworks wrap navigations in transitions for you. Measure with the Profiler and INP (QLT.01.03) before and after.

    Check yourself: Which interactions are good candidates for transitions?

    Tab switches, filtering large lists, and route navigation.

    Finished the five steps? Mark it, and its cards join your reviews.

    Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.

    Interview questions this answers

    • What are transitions in React? When would you use useTransition?
    • What is tearing and how does useSyncExternalStore prevent it?