HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
6 Topics
Chapter•110 Minutes

Advanced React APIs & Patterns

Go beyond everyday hooks into transitions, deferred values, imperative handles, portals, external-store subscriptions, reusable abstractions, and advanced component patterns.

Transitions & useTransition

A transition marks updates as non-urgent. This is useful when an urgent interaction, such as typing, should remain responsive while expensive derived content updates.

The transition API also provides pending state so the UI can communicate that the non-urgent update is being prepared.

Use transitions to improve interaction scheduling, not as a substitute for fixing pathological algorithms or unnecessary rendering.

Transitioning a filter
const [isPending, startTransition] = useTransition();

function handleChange(value) {
  setInput(value);
  startTransition(() => {
    setFilter(value);
  });
}
💡 The input can update urgently while the expensive filtered result is scheduled as non-urgent work.
Key Takeaways
  • Transitions distinguish update priority.
  • Keep urgent controls responsive.
  • Pending UI should explain meaningful background work.

useDeferredValue

useDeferredValue lets a component receive a lagging version of a value so expensive rendering can be deprioritized.

It is useful when the source value is urgent but a consumer is expensive. The consumer may temporarily render using the previous value while React prepares the new one.

Do not use it to hide broken loading logic. The deferred UI should still communicate that it may be showing older data.

Key Takeaways
  • Deferred values can decouple urgent input from expensive consumers.
  • The deferred value may temporarily lag.
  • Use it for responsiveness, not correctness.

Imperative Handles

Sometimes a reusable component needs to expose a small imperative API, such as focus(), scrollToTop(), or open(). An imperative handle can expose a controlled interface instead of leaking internal DOM nodes.

Use this sparingly. Declarative props are usually easier to reason about. Imperative APIs are most appropriate for integration with inherently imperative behavior.

Exposing focus
useImperativeHandle(ref, () => ({
  focus() {
    inputRef.current?.focus();
  }
}), []);
💡 The parent receives a narrow imperative capability rather than direct access to internal implementation.
Key Takeaways
  • Prefer declarative APIs when possible.
  • Expose narrow imperative capabilities when integration requires them.
  • Do not expose internal mutable state unnecessarily.

Portals & Overlay Architecture

Portals render a subtree into a different DOM location while preserving its React relationship. They are commonly used for dialogs, tooltips, menus, and overlays that need to escape clipping or stacking contexts.

Even though the DOM location changes, React context and event relationships follow the React tree. This is useful for building overlays that still belong to the component that controls them.

Accessibility remains your responsibility: focus, labels, keyboard dismissal, and modal semantics must be implemented correctly.

Portal concept
createPortal(
  <div role="dialog" aria-modal="true">...</div>,
  document.body
);
💡 The dialog can escape an ancestor's overflow or stacking context while remaining part of the same React tree.
Key Takeaways
  • Portals solve DOM placement problems, not accessibility automatically.
  • Context relationships remain based on the React tree.
  • Overlays need deliberate focus and keyboard behavior.

Subscribing to External Stores

When React reads data owned by an external store, the subscription must be compatible with React's rendering model. The dedicated external-store subscription API helps React obtain a consistent snapshot and subscribe to changes.

This is particularly relevant to state libraries and applications that integrate existing mutable stores.

The principle is more important than the API name: React needs a reliable snapshot and notification mechanism rather than arbitrary mutable reads during render.

Key Takeaways
  • External store integration needs consistent snapshots.
  • Avoid reading mutable external state without a subscription model.
  • State libraries should integrate with React's scheduling semantics.

Compound Components & Headless Patterns

Compound components allow several components to cooperate through shared context or controlled state. Examples include Tabs, Accordion, Select, and Menu systems.

A headless component separates behavior and accessibility from visual styling. Consumers provide the presentation while the component manages interaction semantics.

These patterns are powerful but can be overused. If a simple prop-based component solves the problem, prefer the simpler API.

Compound tabs concept
<Tabs>
  <Tabs.List>
    <Tabs.Tab value="overview">Overview</Tabs.Tab>
    <Tabs.Tab value="activity">Activity</Tabs.Tab>
  </Tabs.List>
  <Tabs.Panel value="overview">...</Tabs.Panel>
</Tabs>
💡 Compound APIs express relationships clearly while allowing the parent Tabs component to coordinate state.
Key Takeaways
  • Compound components express coordinated behavior.
  • Headless components separate behavior from presentation.
  • Use advanced patterns when they reduce, rather than increase, consumer complexity.