Why are React components expected to be pure functions of props and state?

HighIntermediateReact
Preparing for interviews?

Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.

Quick Answer

Explain why React expects rendering to be a pure computation (UI = f(props, state, context)) and why side effects must be moved to effects/event handlers. Connect it to render vs commit, Concurrent Rendering, StrictMode double-invocation, memoization, and predictable reconciliation. Pure rendering improves predictability and testing, but side effects must live in effects/hooks. Test with StrictMode and rerenders.

Answer

Core idea

React wants rendering to be a deterministic computation: given the same props + state (+ context), the component should return the same UI description. That purity lets React freely re-run renders, pause/abort work, and diff trees safely without causing “real-world” side effects.

Why purity matters

What it enables in React

What breaks if you add side effects in render

Render can run multiple times

Retry / discard renders safely (especially in Concurrent Rendering)

Duplicate API calls, duplicate subscriptions, duplicated logs, inconsistent state

Render can be paused / resumed / interleaved

Scheduling + prioritization without committing to the DOM

Effects happen at the wrong time, race conditions, tearing-like bugs

React uses diffing + memoization

Predictable reconciliation, React.memo, caching, dev tooling

Non-deterministic output makes “same inputs => same UI” false

StrictMode intentionally stress-tests

Double-invocation in dev helps catch unsafe patterns

Impure render causes “works in prod, weird in dev” behavior

Purity is what makes React’s rendering model safe and optimizable

Render vs side effects

Render phase should only compute the next UI tree. Side effects belong in event handlers (user actions) or effects (useEffect/useLayoutEffect) which run after React commits changes.

JSX
// ❌ Impure render: side effects inside render
let renders = 0;

function Profile({ user }) {
  renders++; // side effect: mutating external state

  // side effect: mutating props object
  user.lastSeenAt = Date.now();

  // side effect: starting async work during render
  fetch('/api/track?u=' + user.id);

  return <div>Renders: {renders} — {user.name}</div>;
}
                  

Side effect in render

Why it’s bad

Where it should go instead

Mutating props/state/external variables

Repeated renders produce cumulative mutations and hard-to-debug bugs

Compute derived values immutably; update state via setters

Network calls / subscriptions / timers

Render may be retried/aborted → duplicated work and leaks

useEffect cleanup; subscribe/unsubscribe there

Reading time/randomness (Date.now, Math.random)

Same inputs can yield different UI (non-deterministic)

Initialize once with lazy state init, or store in state

DOM reads/writes

DOM may not match the tree until commit; causes layout issues

useLayoutEffect (reads/writes after commit) or refs

Common impurities React wants you to avoid
JSX
// ✅ Pure render + side effects moved out
function Profile({ user }) {
  // Pure: derived UI only
  return <div>{user.name}</div>;
}

function ProfileWithTracking({ user }) {
  React.useEffect(() => {
    let cancelled = false;

    (async () => {
      try {
        await fetch('/api/track?u=' + user.id);
      } finally {
        // optional: handle completion
      }
    })();

    return () => {
      cancelled = true; // example cleanup flag
    };
  }, [user.id]);

  return <Profile user={user} />;
}
                  

Rule of thumb

If running the component body twice would cause anything “real” to happen twice (API call, subscription, mutation, analytics), it’s not pure. Keep render as a calculation; do real work in effects and event handlers.

Practical scenario
A product card renders purely from props and local state, while data fetching happens in effects.

Common pitfalls

      • Triggering side effects during render.
      • Deriving state incorrectly from props.
      • Relying on mutable props.
Trade-off or test tip
Pure renders are predictable but require disciplined effects. Test with StrictMode and snapshot behavior.

Summary

React expects components to be pure so it can re-run rendering freely (including retries/aborts), apply concurrent scheduling, and reconcile efficiently. Side effects in render break determinism and lead to duplicated work and inconsistent UI; move them to effects/event handlers where React guarantees timing relative to commits.

Similar questions
Guides
9 / 41