React & Modern Frontend Frameworks

React Internals & Reconciliation

5 min read

Understanding how React works under the hood sets you apart from candidates who only know the API surface. Interviewers at Meta and Google specifically test these concepts.

Virtual DOM vs. Fiber Architecture

React does not manipulate the real DOM directly. Instead, it maintains a lightweight JavaScript representation of the UI.

Virtual DOM (React 15 and earlier):

  • React creates a tree of plain JavaScript objects representing the UI
  • On state change, React creates a new tree and diffs it against the previous one
  • The diff (reconciliation) identifies the minimal set of DOM operations needed
  • React applies these operations in a single batch

Fiber Architecture (React 16+):

  • React replaced the recursive, synchronous reconciliation algorithm with Fiber
  • Each component instance is represented by a "fiber" node in a linked list
  • Work can be interrupted, paused, and resumed — the key improvement
  • This enables prioritization: user interactions get higher priority than background updates
Fiber Tree (linked list structure):
  App
   ├── Header (sibling → Sidebar)
   │    └── Nav (child)
   ├── Sidebar (sibling → Main)
   │    └── Menu (child)
   └── Main
        └── Content (child)

The Reconciliation Algorithm

When state changes, React performs reconciliation — comparing the old and new fiber trees:

Rule 1: Different element types → tear down and rebuild

// Old: <div><Counter /></div>
// New: <span><Counter /></span>
// React unmounts Counter entirely and remounts a new instance

Rule 2: Same element type → update attributes only

// Old: <div className="old" title="x" />
// New: <div className="new" title="x" />
// React only updates className, keeps the DOM node

Rule 3: Keys identify list items across renders

// Without keys — React re-renders ALL items when list changes
<ul>
  {items.map(item => <li>{item.name}</li>)}
</ul>

// With keys — React knows exactly which items changed
<ul>
  {items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>

Why keys matter (interview favorite):

  • Without keys, React matches children by index
  • Inserting an item at the beginning shifts all indexes, causing every item to re-render
  • With unique keys, React can match items across renders and only update what changed
  • Keys should be stable, unique identifiers (database IDs), never array indexes for dynamic lists

Concurrent Features

React 18 introduced concurrent rendering, built on Fiber, and React 19 (stable since late 2024) expanded it with Actions, the use() hook, useOptimistic, and native ref as a prop. The concurrent hooks below are stable in all modern React versions:

useTransition

Marks a state update as non-urgent, letting React keep the UI responsive:

function SearchPage() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [isPending, startTransition] = useTransition();

  function handleChange(e) {
    // Urgent: update the input immediately
    setQuery(e.target.value);

    // Non-urgent: update results can be interrupted
    startTransition(() => {
      setResults(filterLargeDataset(e.target.value));
    });
  }

  return (
    <>
      <input value={query} onChange={handleChange} />
      {isPending ? <Spinner /> : <ResultsList results={results} />}
    </>
  );
}

useDeferredValue

Creates a deferred copy of a value that lags behind the current value:

function SearchResults({ query }) {
  // deferredQuery updates only when React has spare time
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;

  return (
    <div style={{ opacity: isStale ? 0.7 : 1 }}>
      <ExpensiveList query={deferredQuery} />
    </div>
  );
}

Key difference: useTransition wraps the state setter (you control when to transition). useDeferredValue wraps a value (the component consuming the value decides to defer).

React Compiler

The React Compiler reached 1.0 stable in 2025 and ships as an opt-in Babel/SWC plugin alongside React 19. It is a build-time tool that auto-memoizes components, letting you write idiomatic React without manual memo/useMemo/useCallback in most cases:

// Before React Compiler: manual memoization
const MemoizedChild = React.memo(({ data }) => {
  const processed = useMemo(() => expensiveCalc(data), [data]);
  const handler = useCallback(() => doSomething(data), [data]);
  return <div onClick={handler}>{processed}</div>;
});

// With React Compiler: write natural code
// The compiler automatically adds memoization where needed
function Child({ data }) {
  const processed = expensiveCalc(data);
  const handler = () => doSomething(data);
  return <div onClick={handler}>{processed}</div>;
}
// The compiler transforms this at build time to include
// the equivalent of memo, useMemo, and useCallback

How React stopped asking you to hand-optimise

Recursive reconciler

React 15 and earlier diffed the whole tree synchronously. Once started, an update could not be interrupted — a large render blocked input until it finished

Fiber

React 16 rebuilt the reconciler around interruptible units of work. This is the change everything after it depends on; without it, priority means nothing

Concurrent rendering

React 18 exposed the priority model to you: `useTransition` and `useDeferredValue` let you mark an update as interruptible rather than hoping it is fast

Actions and `use()`

React 19 folded pending states, errors, and optimistic updates into the form and Action model, removing a category of hand-written boilerplate

React Compiler

Memoisation becomes a build step rather than something you remember to write. The direction of travel: less manual optimisation, not more

Interview tip: when asked about React performance, walk this line rather than listing hooks. The point is not that memoisation got easier — it is that each step moved a decision from the developer to the runtime or the build, and being able to say which decision moved is what separates a useful answer from a version-number recital.

Hooks are next — specifically the ones candidates use daily and still get asked to explain. :::

Quiz

Module 3: React & Modern Frontend Frameworks

Take Quiz
Was this lesson helpful?

Sign in to rate