diagram.mmd — state
Component Lifecycle state diagram

The component lifecycle is the set of distinct phases a UI component passes through from the moment it is created and added to the DOM to the moment it is removed — and the hooks developers can use to run code at each transition.

All major JavaScript frameworks — React, Vue, Angular, Svelte — expose a lifecycle model, though the naming varies. React hooks like useEffect and useLayoutEffect map onto these phases. Vue exposes onMounted, onUpdated, onBeforeUnmount. Angular uses ngOnInit, ngOnChanges, ngOnDestroy. Despite the naming differences, the underlying phase model is consistent.

Mounting is the initial phase where the component is instantiated, its initial state and props are set, and it renders for the first time into the DOM. During mounting, the constructor (or setup() in Vue) runs, then the render function, then the framework attaches the output to the real DOM. After the DOM is available, componentDidMount / onMounted / useEffect with an empty dependency array fires. This is the correct place to start data fetches, subscribe to event emitters, or initialize third-party libraries that need a DOM node.

Updating happens whenever the component's state or incoming props change. The render function re-runs, the framework performs reconciliation (see Virtual DOM Diffing), and after the DOM is updated, componentDidUpdate / onUpdated fires. React's useEffect dependencies list controls which updates trigger a given effect.

Unmounting occurs when the component is removed from the component tree — for example, when the user navigates away or a condition renders it out. componentWillUnmount / onBeforeUnmount fires here and is the correct place to cancel timers, unsubscribe from observables, remove event listeners, and clean up any resources to prevent memory leaks. In React, useEffect cleanup functions run at this phase and also before each re-run of the effect.

Understanding the lifecycle is essential for writing side-effect-free, leak-free components and for correctly timing data fetches and subscriptions.

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 component lifecycle is the sequence of phases a UI component passes through — mounting (creation and first render), updating (re-renders due to state or prop changes), and unmounting (removal from the tree) — along with the hooks developers use to run code at each transition.
In React's function component model, `useEffect` with an empty dependency array (`[]`) runs after the first mount. `useEffect` with specified dependencies runs after any render where those values changed. The cleanup function returned by `useEffect` runs on unmount and before each re-run of the effect, covering both `componentDidMount`/`componentDidUpdate`/`componentWillUnmount` in a single API.
Data fetches belong in the mount phase — after the component is attached to the DOM. In React, use `useEffect` with an empty dependency array, or a data-fetching library like React Query or SWR that manages lifecycle correctly. Fetching during render (outside effects) causes infinite loops; fetching in `useLayoutEffect` blocks paint unnecessarily.
The most common mistakes are: missing cleanup in `useEffect` (causing memory leaks from uncleared timers or unremoved event listeners), adding values to the render function but forgetting to include them in the `useEffect` dependency array (stale closures), and triggering data fetches unconditionally without a dependency guard so they re-run on every update.
mermaid
stateDiagram-v2 [*] --> Mounting : Component added to tree Mounting --> Mounted : Initial render + DOM attached state Mounting { [*] --> Constructor Constructor --> RenderFunction RenderFunction --> DOMAttached } Mounted --> Updating : Props or state change state Mounted { [*] --> RunMountedHooks RunMountedHooks --> IdleWaitingForUpdates } Updating --> Mounted : Re-render complete + DOM patched state Updating { [*] --> ReRunRender ReRunRender --> ReconcileDiff ReconcileDiff --> ApplyDOMPatches ApplyDOMPatches --> RunUpdateHooks } Mounted --> Unmounting : Component removed from tree Unmounting --> [*] : Cleanup complete state Unmounting { [*] --> RunCleanupCallbacks RunCleanupCallbacks --> RemoveEventListeners RemoveEventListeners --> DestroyInstance }
Copied to clipboard