When I first started working with React, I often struggled to understand when and why certain methods were called. At that time, debugging felt like chasing shadows; sometimes my component updated as expected, and sometimes it didn’t.
Over the years, I learned that understanding the lifecycle methods is the key to building predictable and optimized React applications.
In this tutorial, I’ll walk you through React component lifecycle methods in class components and also touch on how things are done in functional components with hooks.
What Are React Lifecycle Methods?
Every React component goes through three main phases:
- Mounting – When the component is first created and added to the DOM.
- Updating – When the component re-renders due to changes in props or state.
- Unmounting – When the component is removed from the DOM.
Lifecycle methods are special functions you can use to run code at specific points in these phases. Think of them as checkpoints in the life of a component.
Mounting Phase
This is when the component is created and inserted into the DOM.
constructor()
class UserProfile extends React.Component {
constructor(props) {
super(props);
this.state = { name: "John Doe", age: 30 };
console.log("Constructor: State initialized");
}
render() {
return <h2>{this.state.name} - {this.state.age}</h2>;
}
}You can refer to the screenshot below to see the output.

The constructor is the first method called. It’s used to initialize state and bind methods.
componentDidMount()
class Dashboard extends React.Component {
componentDidMount() {
console.log("ComponentDidMount: Data fetching starts here");
fetch("https://jsonplaceholder.typicode.com/users/1")
.then(response => response.json())
.then(data => console.log("Fetched User:", data));
}
render() {
return <h2>Dashboard Loaded</h2>;
}
}You can refer to the screenshot below to see the output.

componentDidMount runs after the component is rendered. It’s perfect for fetching data or setting up subscriptions.
Updating Phase
This happens when props or state change.
shouldComponentUpdate()
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
shouldComponentUpdate(nextProps, nextState) {
console.log("ShouldComponentUpdate: Deciding re-render");
return nextState.count <= 5;
}
render() {
return (
<div>
<h2>Count: {this.state.count}</h2>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}This method lets you control whether the component should re-render. It’s useful for performance optimization.
componentDidUpdate()
class UserStatus extends React.Component {
constructor(props) {
super(props);
this.state = { online: false };
}
componentDidUpdate(prevProps, prevState) {
if (prevState.online !== this.state.online) {
console.log("User status changed:", this.state.online ? "Online" : "Offline");
}
}
render() {
return (
<div>
<h2>Status: {this.state.online ? "Online" : "Offline"}</h2>
<button onClick={() => this.setState({ online: !this.state.online })}>
Toggle Status
</button>
</div>
);
}
}You can refer to the screenshot below to see the output.

componentDidUpdate runs after every update. It’s great for reacting to state or prop changes.
Unmounting Phase
This is when the component is removed from the DOM.
componentWillUnmount()
class Timer extends React.Component {
componentDidMount() {
this.timer = setInterval(() => {
console.log("Timer running...");
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
console.log("ComponentWillUnmount: Timer cleared");
}
render() {
return <h2>Timer Active</h2>;
}
}This method is used to clean up resources like timers, event listeners, or subscriptions.
Lifecycle Methods Flow
Here’s the order in which lifecycle methods are called:
- constructor
- render
- componentDidMount
- shouldComponentUpdate
- render
- componentDidUpdate
- componentWillUnmount
Lifecycle in Functional Components (Hooks)
With React Hooks, we don’t use lifecycle methods directly. Instead, we use the useEffect hook.
import React, { useState, useEffect } from "react";
function Weather() {
const [city, setCity] = useState("New York");
useEffect(() => {
console.log("Fetching weather for:", city);
return () => {
console.log("Cleaning up before city changes or unmount");
};
}, [city]);
return (
<div>
<h2>City: {city}</h2>
<button onClick={() => setCity("Los Angeles")}>Change City</button>
</div>
);
}You can refer to the screenshot below to see the output.

useEffect combines componentDidMount, componentDidUpdate, and componentWillUnmount into one function.
Practical Example – User Dashboard
Let’s combine multiple lifecycle methods into a real-world example:
class UserDashboard extends React.Component {
constructor(props) {
super(props);
this.state = { user: null };
}
componentDidMount() {
console.log("Fetching user data...");
fetch("https://jsonplaceholder.typicode.com/users/2")
.then(response => response.json())
.then(data => this.setState({ user: data }));
}
componentDidUpdate(prevProps, prevState) {
if (prevState.user !== this.state.user) {
console.log("User data updated:", this.state.user);
}
}
componentWillUnmount() {
console.log("Cleaning up before dashboard unmounts...");
}
render() {
return (
<div>
<h2>User Dashboard</h2>
{this.state.user ? (
<p>{this.state.user.name} - {this.state.user.email}</p>
) : (
<p>Loading...</p>
)}
</div>
);
}
}This example shows how lifecycle methods work together to fetch, update, and clean up data.
Conclusion
Lifecycle methods in React may seem overwhelming at first, but once you understand the flow, they become second nature.
I’ve shown you how to use them in class components and how to achieve the same results with hooks in functional components.
If you’re building apps for real-world scenarios, like dashboards, timers, or user profiles, mastering these methods will save you hours of debugging.
You may like to read other React tutorials:
- React Component Folder Structure Best Practices
- Use react-vertical-timeline-component in React
- React cannot update a component while rendering a different component
- How to Use React Component with Children

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.