React Curriculum

Lifecycle Transitions: Mount, Update & Unmount

Medium100% Free~20 mins#react#lifecycle#mount#unmount#update#useeffect#strictmode
Interview Answer (30-Second Summary)

In functional React, components do not have lifecycle methods; instead, they synchronize state with external systems via useEffect. Mounting runs initial setup, updating re-runs effects whose dependencies changed after running cleanup, and unmounting runs final effect teardown.

Key Learning Objectives
✓

Map legacy class lifecycle methods (componentDidMount, componentDidUpdate, componentWillUnmount) to useEffect.

✓

Understand the setup and cleanup lifecycle in functional components.

✓

Explain why thinking in "synchronization" is superior to thinking in "lifecycle events".

✓

Diagnose why React StrictMode unmounts and remounts effects in development.

The Interview Problem & Context

Compare class component lifecycle methods to functional component effect synchronizations. How does the mental model of synchronization differ from discrete lifecycle hooks?

1// Legacy Class Component Lifecycle
2class LegacyTimer extends React.Component {
3 componentDidMount() {
4 this.timerId = setInterval(this.tick, 1000);
5 }
6 componentDidUpdate(prevProps) {
7 if (prevProps.roomId !== this.props.roomId) {
8 this.reconnect();
9 }
10 }
11 componentWillUnmount() {
12 clearInterval(this.timerId);
13 }
14}
15
16// Modern Functional Component: Unified Synchronization Lifecycle
17function ModernTimer({ roomId }: { roomId: string }) {
18 useEffect(() => {
19 // 1. Setup: Runs on mount AND on update if roomId changed
20 const connection = createConnection(roomId);
21 connection.connect();
22
23 // 2. Cleanup: Runs on unmount AND before re-running when roomId changes
24 return () => {
25 connection.disconnect();
26 };
27 }, [roomId]); // Synchronized with roomId
28}
Deep Architectural Explanation

From Lifecycle Methods to Synchronization

In class components, lifecycle methods split related logic across three disconnected methods:

  • Setup in componentDidMount
  • Sync updates in componentDidUpdate
  • Cleanup in componentWillUnmount
    Developers routinely forgot to update subscriptions in componentDidUpdate, causing stale socket connections and memory leaks.

The Functional Synchronization Paradigm

In functional components, useEffect unifies setup and cleanup into a single declarative block:

  1. Mount: React runs the component render function, commits to the DOM, then runs the effect setup function.
  2. Update: When dependencies change, React runs the previous render's cleanup function, commits the new DOM, and runs the new effect setup function.
  3. Unmount: React runs the final cleanup function.

Development StrictMode Double-Mount

In React 18+, development mode intentionally mounts, unmounts, and re-mounts components:
Setup -> Cleanup -> Setup
This immediately proves whether your cleanup function properly tears down subscriptions, timers, or abort controllers!

Common Interview Traps & Pitfalls
✕

Treating useEffect as an exact synonym for componentDidMount by passing an empty array [] while reading dynamic props.

✕

Omitting the cleanup function when adding event listeners or setting intervals, causing severe memory leaks.

✕

Disabling React StrictMode because "my effects run twice in development" instead of fixing missing cleanups.

Senior Interviewer Follow-Up Probes
?

What is the exact execution order of cleanups and effects across parent and child components?

?

Why does React 18 execute effect cleanup before the next effect setup rather than waiting until unmount?

?

How does useLayoutEffect alter the timing of DOM mutation vs effect execution?

Frequently Asked Interview Questions
How does useEffect replace componentDidMount, componentDidUpdate, and componentWillUnmount?

useEffect runs setup on mount, runs cleanup and re-setup whenever specified dependencies change (update), and runs final cleanup when the component unmounts.

React StrictMode mounts, unmounts, and re-mounts components to ensure effects properly clean up their resources and support future features like Concurrent Fast Refresh and state preservation.

It executes right before the effect re-runs due to a dependency change, and when the component unmounts from the DOM.

The effect will execute its setup and cleanup functions on every single render pass, which can cause severe performance issues or infinite loops if state is updated inside.

Because your code ensures the UI is always in sync with current props and state, avoiding common bugs where developers implemented mount logic but forgot to handle updates.