React Component Lifecycle Explained: Birth, Life & Death ๐งฌ
React components go through stages just like us humans โ they're born, they live, and eventually they die. Let's understand this in plain English with zero jargon.
You open Swiggy to order food. ๐
The moment you tap the app, the home screen appears (born). You scroll, search, and it updates as you type (lives). You close the app โ the screen vanishes (dies).
That's exactly how a React component works.
Every component has three stages in life:
๐ข MOUNT โ component appears on screen
๐ UPDATE โ something changes (user types, data loads)
๐ด UNMOUNT โ component disappears from screen๐ข Stage 1: Birth (Mount)
When a component first appears on the screen, React runs it for the very first time.
Think of it like Zomato loading your restaurant list โ the moment the page opens, it fetches your location, loads the cards, shows the UI. All of that happens once at birth.
In code, this is useEffect with an empty array:
useEffect(() => {
fetchRestaurants(); // runs ONCE when component appears
}, []);The [] at the end = "run this only at birth, never again."
Memory trick: Empty [] = Empty womb = Born once ๐ฃ
๐ Stage 2: Life (Update)
Now you're using the app. You change the city from Mumbai โ Delhi. The restaurant list re-renders with new data.
That's an update. React watches for state or prop changes and re-runs the component.
const [city, setCity] = useState("Mumbai");
useEffect(() => {
fetchRestaurants(city); // runs every time 'city' changes
}, [city]);Every time city changes โ effect runs โ new restaurants load. ๐
Memory trick: [city] in the array = "Watch this thing, run when it changes."
โ Stage 3: Death (Unmount)
You navigate away from the restaurant page. React removes that component from the screen entirely.
But here's the problem โ if you had a timer running, or an API call in progress, it keeps running even after the component is gone. Like leaving a Swiggy order open after you've already eaten. ๐
You need to clean up before dying:
useEffect(() => {
const timer = setInterval(checkDelivery, 1000);
return () => {
clearInterval(timer); // runs when component dies
};
}, []);That return () => {} inside useEffect is the cleanup function โ it runs at death.
The Full Picture
Component created
โ
๐ข MOUNT
useEffect([]) runs
โ
State/props change?
โ
๐ UPDATE
useEffect([dep]) runs
โ
Component removed
โ
โ UNMOUNT
cleanup function runsLifecycle vs. Human Life ๐งโ๐คโ๐ง
| Human Life | React Component | Code |
| -------------- | ------------------- | --------------------------- |
| Born | Mounted | useEffect(() => {}, []) |
| Growing up | Re-rendering | useState, useEffect |
| Daily habits | Watching for change | useEffect([dep]) |
| Death | Unmounted | return () => cleanup() |
Class vs. Functional (Quick Look)
If you ever see older React code with class components, the lifecycle looks like this:
class OldSchool extends React.Component {
componentDidMount() { /* birth */ }
componentDidUpdate() { /* update */ }
componentWillUnmount(){ /* death */ }
}In modern React (hooks), all three collapse into just useEffect. One hook to rule them all. ๐
The Full Flow as a Diagram
One-Line Memory Tricks ๐ง
useEffect(() => {}, [])โ Runs once at birthuseEffect(() => {}, [x])โ Runs when x changesreturn () => {}inside effect โ Runs at death- No deps array? โ Runs every single render (usually avoid this)
Real Scenario: Swiggy Live Tracker ๐ต
Let's say you're building that little "order is 2km away" tracker:
function DeliveryTracker({ orderId }) {
const [distance, setDistance] = useState(null);
useEffect(() => {
// ๐ข BIRTH: start tracking
const interval = setInterval(async () => {
const d = await fetchDistance(orderId);
setDistance(d);
}, 3000);
// โ DEATH: stop tracking
return () => clearInterval(interval);
}, [orderId]); // ๐ UPDATE: if order changes, restart
return <p>Delivery is {distance}km away</p>;
}Three lines of logic. Three lifecycle stages. One clean component. โจ
TL;DR
React components live a full life:
- Mount โ appears on screen, run side effects once
- Update โ state/props changed, re-render, re-run watched effects
- Unmount โ gone from screen, run cleanup
useEffect is your lifecycle manager. Master it, and you've mastered 70% of React.
Now go build something. ๐
Related Posts
Demystifying the Database Index: A B-Tree Explained Simply
Confused about database performance? Here is a database index b-tree explained simply, showing how database indexes work under the hood with TypeScript examples.
Under the Hood: How HTTP/2 and HTTP/3 Differ in Production
An in-depth technical explainer on how HTTP/2 and HTTP/3 differ, exploring TCP head-of-line blocking, QUIC over UDP, connection migration, and real-world performance impacts.
How TypeScript Generics Actually Work
A clear explanation of how TypeScript generics work โ real patterns, constraints, and when not to use them, with minimal code.