Lifecycle Methods in Class Components

Introduction

React class components, before the introduction of functional components with hooks, were the primary way to build complex React applications. Class components have a unique feature called lifecycle methods that allow developers to run code at specific points in a component’s life. These lifecycle methods provide hooks into different stages of a component’s existence, such as when it is created, updated, or destroyed.

Understanding lifecycle methods is essential for developers who maintain or work with React codebases written in class components. Even though functional components with hooks are the modern standard, lifecycle methods remain relevant because many enterprise-level applications still rely heavily on class-based components.

In this article, we will explore the three main phases of the React component lifecycle—mounting, updating, and unmounting—and the lifecycle methods associated with each phase. We will also provide detailed explanations, code examples, best practices, and real-world scenarios.


What Is a Component Lifecycle?

The component lifecycle refers to the series of events that happen from the time a component is created (mounted) until it is removed (unmounted) from the DOM.

Each React component goes through three major phases:

  1. Mounting – When the component is created and inserted into the DOM.
  2. Updating – When the component re-renders due to changes in props or state.
  3. Unmounting – When the component is removed from the DOM.

Lifecycle methods are special methods in class components that run automatically at each phase.


The Three Phases of Lifecycle

  • Mounting Phase: Occurs when the component is first initialized and added to the DOM.
  • Updating Phase: Occurs whenever props or state change and the component re-renders.
  • Unmounting Phase: Occurs when the component is removed from the DOM.

Mounting Phase

The mounting phase is the first phase of the lifecycle. It happens when a component is being created and inserted into the DOM for the first time.

The lifecycle methods in the mounting phase are:

  1. constructor()
  2. static getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

1. constructor()

The constructor() method is the first method called when a component is created. It is used to:

  • Initialize state
  • Bind methods
  • Set up initial values

Example

class MyComponent extends React.Component {
  constructor(props) {
super(props);
this.state = {
  count: 0
};
this.increment = this.increment.bind(this);
} increment() {
this.setState({ count: this.state.count + 1 });
} render() {
return (
  <div>
    <p>Count: {this.state.count}</p>
    <button onClick={this.increment}>Increment</button>
  </div>
);
} }

2. static getDerivedStateFromProps()

This method is rarely used but is important. It runs before render() both on the initial mount and on updates. Its purpose is to synchronize state with props.

static getDerivedStateFromProps(props, state) {
  if (props.value !== state.value) {
return { value: props.value };
} return null; }

3. render()

The render() method is required in every class component. It describes the UI that should be displayed. It must return JSX or null.

class Welcome extends React.Component {
  render() {
return <h1>Hello, {this.props.name}</h1>;
} }

4. componentDidMount()

This method runs once after the component has been mounted into the DOM. It is often used for:

  • Fetching data from APIs
  • Adding event listeners
  • Starting timers
class DataFetcher extends React.Component {
  state = { data: [] };

  componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/posts")
  .then(response => response.json())
  .then(data => this.setState({ data }));
} render() {
return (
  <ul>
    {this.state.data.map(item => (
      <li key={item.id}>{item.title}</li>
    ))}
  </ul>
);
} }

Updating Phase

The updating phase occurs whenever a component’s state or props change. This phase allows the component to re-render with updated data.

The lifecycle methods in the updating phase are:

  1. static getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

1. shouldComponentUpdate()

This method determines whether a component should re-render or not. It returns a boolean value. By default, components re-render on every update, but you can override this for performance optimization.

shouldComponentUpdate(nextProps, nextState) {
  return nextProps.value !== this.props.value;
}

2. render() (During Updates)

As in mounting, render() is called during updates to re-render the UI.


3. getSnapshotBeforeUpdate()

This method is called just before changes from the virtual DOM are applied to the real DOM. It allows capturing information, such as scroll position, before the DOM updates.

getSnapshotBeforeUpdate(prevProps, prevState) {
  if (prevProps.list.length < this.props.list.length) {
return this.listRef.scrollHeight;
} return null; }

4. componentDidUpdate()

This method is invoked immediately after the component updates. It is commonly used for:

  • Fetching data based on new props
  • Performing side effects after updates
componentDidUpdate(prevProps, prevState) {
  if (this.props.userId !== prevProps.userId) {
this.fetchData(this.props.userId);
} }

Unmounting Phase

The unmounting phase happens when a component is removed from the DOM. There is only one lifecycle method in this phase:

componentWillUnmount()

This method is used for cleanup, such as:

  • Removing event listeners
  • Canceling API calls
  • Clearing timers
class Timer extends React.Component {
  componentDidMount() {
this.interval = setInterval(() =&gt; {
  console.log("Tick");
}, 1000);
} componentWillUnmount() {
clearInterval(this.interval);
} render() {
return &lt;h1&gt;Timer Running...&lt;/h1&gt;;
} }

Full Lifecycle Flow

When a component is created:

  1. constructor()
  2. getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

When updated:

  1. getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

When unmounted:

  1. componentWillUnmount()

Example: Complete Lifecycle Demonstration

class LifecycleDemo extends React.Component {
  constructor(props) {
super(props);
this.state = { count: 0 };
console.log("Constructor");
} static getDerivedStateFromProps(props, state) {
console.log("getDerivedStateFromProps");
return null;
} componentDidMount() {
console.log("componentDidMount");
} shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
return true;
} getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
return null;
} componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate");
} componentWillUnmount() {
console.log("componentWillUnmount");
} render() {
console.log("Render");
return (
  &lt;div&gt;
    &lt;p&gt;Count: {this.state.count}&lt;/p&gt;
    &lt;button onClick={() =&gt; this.setState({ count: this.state.count + 1 })}&gt;
      Increment
    &lt;/button&gt;
  &lt;/div&gt;
);
} }

If you mount and interact with this component, you will see lifecycle methods logged in the console, showing when each one executes.


Best Practices for Lifecycle Methods

  1. Keep Logic Focused – Avoid putting too much logic inside lifecycle methods.
  2. Use componentDidMount for Side Effects – Fetch data, set up subscriptions here.
  3. Use componentWillUnmount for Cleanup – Always clear intervals or subscriptions.
  4. Avoid Deprecated Methods – Methods like componentWillMount are deprecated.
  5. Optimize Performance – Use shouldComponentUpdate for performance improvements.

Deprecated Lifecycle Methods

Some lifecycle methods are deprecated in newer versions of React (16.3+). They should not be used:

  • componentWillMount()
  • componentWillReceiveProps()
  • componentWillUpdate()

React recommends alternatives like getDerivedStateFromProps and componentDidUpdate.


Lifecycle Methods vs Hooks

In modern React, functional components with hooks (useEffect, useState) replace lifecycle methods. For example:

  • componentDidMountuseEffect with empty dependency array
  • componentDidUpdateuseEffect with dependencies
  • componentWillUnmount → Cleanup function in useEffect

Real-World Use Cases

  1. Data Fetching – Fetch data when the component mounts.
  2. Event Listeners – Add in componentDidMount, remove in componentWillUnmount.
  3. Performance Optimizations – Use shouldComponentUpdate.
  4. DOM Measurements – Use getSnapshotBeforeUpdate for scroll tracking.
  5. Timers – Start in componentDidMount, clear in componentWillUnmount.

Common Mistakes

  • Fetching data in render() instead of componentDidMount.
  • Forgetting to remove event listeners in componentWillUnmount.
  • Updating state inside componentDidUpdate without conditions, leading to infinite loops.
  • Overusing lifecycle methods for logic better suited in plain functions.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *