diagram.mmd — flowchart
React Rendering Lifecycle flowchart diagram

React's rendering lifecycle is the sequence of phases React runs whenever a component's state or props change — from scheduling the update through reconciliation to committing the result to the DOM and running side effects.

React's architecture since version 16 is built around the Fiber reconciler, which splits rendering into two main phases: the render phase (also called the reconciliation phase) and the commit phase. This split is fundamental to React's ability to interrupt, pause, and resume work — the mechanism behind Concurrent Mode features like useTransition and Suspense.

The lifecycle begins when a state update is triggered — via useState setter, useReducer dispatch, or a context value change. React schedules the update at a priority level (urgent updates like typing happen synchronously; deferred updates like data loading can be interrupted). During the render phase, React calls the component function again, gets the new JSX, and runs the reconciliation algorithm against the previous fiber tree (see Virtual DOM Diffing). This phase is pure and side-effect-free — React may call the render function multiple times in Strict Mode to surface impurity bugs. Because it produces no side effects, it can be safely interrupted.

The commit phase cannot be interrupted. React walks the effect list built during reconciliation and applies DOM mutations: insertions, updates, and deletions. This phase has three sub-phases: before mutation (reads the DOM for snapshot values), mutation (applies DOM changes), and layout (fires useLayoutEffect synchronously). After paint, React fires useEffect callbacks asynchronously on the microtask queue — this is where data fetches, subscriptions, and analytics calls belong. useLayoutEffect fires synchronously after DOM mutation but before paint, making it the correct place for DOM measurements that would flash visually if deferred.

React.memo, useMemo, and useCallback are bailout mechanisms that short-circuit the render phase for components and values that haven't changed, reducing work for the reconciler. Understanding where each hook fires relative to these phases is the key to avoiding stale closure bugs and unnecessary renders.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

The React rendering lifecycle is the sequence of phases React runs when a component's state or props change: scheduling the update at a priority level, the render phase (calling component functions and running reconciliation), and the commit phase (applying DOM mutations and firing effects). Since React 16, this is powered by the Fiber architecture.
The render phase is pure and interruptible — React calls component functions to produce new JSX and runs the reconciliation diff, but makes no DOM changes. This phase may run multiple times in Concurrent Mode. The commit phase is synchronous and uninterruptible — React applies all DOM mutations, then fires `useLayoutEffect` synchronously and `useEffect` asynchronously after paint.
`useLayoutEffect` fires synchronously after the DOM mutations are applied but before the browser paints. Use it when you need to read or write the DOM immediately after render to avoid visual flicker (e.g., measuring an element to position a tooltip). `useEffect` fires asynchronously after paint — it is the correct place for data fetches, subscriptions, and analytics that do not need to block the visual update.
Creating new object or function references on every render (breaking `React.memo` and `useMemo` bail-outs), running expensive computations directly in the render function without `useMemo`, dispatching state updates inside `useEffect` without a conditional guard (infinite render loops), and not understanding that `useEffect` dependencies must be exhaustive to avoid stale closures.
In legacy synchronous rendering, React processes the entire update tree in one uninterruptible pass, potentially blocking the main thread. In Concurrent Mode, React can pause, resume, and abort render-phase work at priority boundaries using `useTransition` and `startTransition`. This keeps the UI responsive during heavy re-renders by deferring low-priority updates while urgent updates (like typing) are processed immediately.
mermaid
flowchart TD A[State or Props Change Triggered] --> B[React Schedules Update] B --> C{Priority check} C -- Urgent update --> D[Synchronous render] C -- Deferred update --> E[Concurrent render - interruptible] D --> F[Render Phase — Call Component Function] E --> F F --> G{Bailout possible?} G -- React.memo or shouldComponentUpdate --> H[Skip re-render] G -- No bailout --> I[Produce New Fiber Tree] I --> J[Reconcile Diffs vs Previous Tree] J --> K[Build Effect List] K --> L[Commit Phase — Before Mutation] L --> M[Commit Phase — Apply DOM Mutations] M --> N[Commit Phase — Layout Effects] N --> O[Browser Paints Frame] O --> P[Run useEffect Callbacks] style O fill:#3b82f6,color:#fff style P fill:#22c55e,color:#fff
Copied to clipboard