Unraveling the Depth of React Class Components

Unraveling the Depth of React Class Components

A Comprehensive Exploration

Introduction

React, the JavaScript library for building user interfaces presents developers with various paradigms to architect their applications. Despite the rise of functional components and hooks, React class components remain a cornerstone in many projects. In this in-depth guide, we'll journey through React class components, exploring their features, advantages, and practical examples to harness their power effectively

Understanding React Class Components

React class components are JavaScript classes that extend React.Component. They encapsulate UI logic, state management, and lifecycle methods within a structured class-based approach. Let's delve into the core features of React class components with illustrative examples.

Create a Class Component

To create a class component in React, you define a JavaScript class that extends React.Component. This class encapsulates the behaviour and rendering logic of your component

import React, { Component } from 'react';

class MyComponent extends Component {
  render() {
    return <div>Hello, World!</div>;
  }
}

Component Constructor

In React, class components are JavaScript classes that extend from React.Component and are used to define the UI logic and behavior of a part of the application. Before the advent of functional components and hooks, class components were the primary way to create reusable and maintainable UI components in React.

The component constructor is a special method within a class component that gets invoked when an instance of the component is created. It serves several key purposes:

  1. Initialization: The constructor is where you initialize the state of the component, bind event handlers, and perform any other setup necessary for the component to function properly.

  2. State Initialization: Inside the constructor, you can initialize the initial state of the component by assigning an object to this.state. State is used to store data that affects the rendering of the component. For example

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
}
  1. Binding Methods: In JavaScript, the value of this is determined by how a function is called. In React class components, if you define custom methods for event handling or other purposes, you typically need to bind them to the instance of the component in the constructor to ensure that this refers to the component instance when the method is called
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }
}
  1. Super Constructor Call: It's important to call super(props) as the first statement in the constructor. This is necessary to ensure that the parent class (React.Component) is properly initialized and that you have access to this.props within the constructor.
constructor(props) {
  super(props);
  // Initialize state and bind methods here
}
  1. Avoiding State in Constructor: With the advent of ES6 class properties and arrow functions, you can define state and event handler methods outside of the constructor. This allows for cleaner and more concise code
class MyComponent extends React.Component {
  state = {
    count: 0
  };

  handleClick = () => {
    this.setState({ count: this.state.count + 1 });
  };
}

Props

props (short for properties) are a fundamental concept used for passing data from a parent component to a child component. They are immutable and help in creating reusable and modular components within your application.

  1. Passing Props: Props are passed from parent components to child components as attributes similar to HTML attributes. They are passed during the instantiation of the child component in the JSX syntax.

     // ParentComponent.js
     import React, { Component } from 'react';
     import ChildComponent from './ChildComponent';
    
     class ParentComponent extends Component {
       render() {
         return <ChildComponent name="John" age={30} />;
       }
     }
    
    1. Accessing Props: Inside the child component, props are accessible via this.props in class components

       // ChildComponent.js
       import React, { Component } from 'react';
      
       class ChildComponent extends Component {
         render() {
           return (
             <div>
               <p>Name: {this.props.name}</p>
               <p>Age: {this.props.age}</p>
             </div>
           );
         }
       }
      
    2. Immutable Nature: Props are immutable, meaning that child components cannot modify the props received from their parent components. They are read-only within the child component.

    3. Default Props: You can also define default values for props using the defaultProps property. If a prop is not provided by the parent component, the default value will be used instead.

       class ChildComponent extends Component {
         render() {
           return (
             <div>
               <p>Name: {this.props.name}</p>
               <p>Age: {this.props.age}</p>
             </div>
           );
         }
       }
      
       ChildComponent.defaultProps = {
         name: 'Anonymous',
         age: 0
       };
      
    4. Type Checking with PropTypes: While not mandatory, it's a good practice to define PropTypes for your components. PropTypes help in documenting the expected types of props, which can aid in debugging and catching potential issues early.

       import PropTypes from 'prop-types';
      
       class ChildComponent extends Component {
         render() {
           return (
             <div>
               <p>Name: {this.props.name}</p>
               <p>Age: {this.props.age}</p>
             </div>
           );
         }
       }
      
       ChildComponent.propTypes = {
         name: PropTypes.string.isRequired,
         age: PropTypes.number.isRequired
       };
      

Props in the Constructor

In React class components, props are typically accessed directly through the this.props object within methods like render() or custom methods defined within the class. Generally, you don't manipulate props directly because they are meant to be immutable. However, if you need to access props within the constructor for some specific initialization logic, you can certainly do so.

import React, { Component } from 'react';

class MyComponent extends Component {
  constructor(props) {
    super(props);
    // Access props in the constructor
    console.log(props);

    // You can use props to initialize state
    this.state = {
      value: props.initialValue
    };
  }

  render() {
    return (
      <div>
        <p>Initial Value: {this.state.value}</p>
      </div>
    );
  }
}

export default MyComponent;

In this example:

  • The constructor method is called when the component is initialized. It takes props as its argument.

  • You call super(props) to call the constructor of the parent class (which is Component in this case) and pass props to it.

  • Within the constructor, you have access to props, so you can log them or use their values to initialize the component's state, as shown in the example

Components in Components

When discussing components within components in React class components, it's essential to understand how React allows you to compose your UI by breaking it down into smaller, reusable pieces. This composability is one of the key strengths of React, enabling developers to build complex user interfaces while maintaining a clear and modular code structure.

Nested Components

Nested components refer to the practice of rendering one component within another component. This can be achieved by simply including the component tag inside the JSX of another component.

// ParentComponent.js
import React, { Component } from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends Component {
  render() {
    return (
      <div>
        <h1>Parent Component</h1>
        <ChildComponent />
      </div>
    );
  }
}

Passing Props to Nested Components

One of the most common patterns in React is passing data from parent components to child components through props

// ParentComponent.js
import React, { Component } from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends Component {
  render() {
    return (
      <div>
        <h1>Parent Component</h1>
        <ChildComponent name="John" />
      </div>
    );
  }
}

Hierarchical Component Structure

React applications often have a hierarchical structure where components are nested within each other, forming a tree-like hierarchy. Each component represents a different level of abstraction or responsibility

// GrandParentComponent.js
import React, { Component } from 'react';
import ParentComponent from './ParentComponent';

class GrandParentComponent extends Component {
  render() {
    return (
      <div>
        <h1>GrandParent Component</h1>
        <ParentComponent />
      </div>
    );
  }
}

Reusability and Maintainability

By breaking down the UI into smaller, reusable components, you can enhance the reusability and maintainability of your codebase. Components can be reused across different parts of your application, promoting consistency and reducing duplication.

Component Composition

React encourages the composition of components, where complex UI elements are built by combining simpler components together. This promotes a modular approach to building user interfaces, making it easier to understand and manage the codebase.

Components in Files

When discussing components spread across multiple files in React class components, it's crucial to highlight how this approach enhances code organization, readability, and maintainability

Organizing Components in Files

Organizing components in separate files allows developers to maintain a clear and structured project hierarchy. Each component resides in its own file, making it easier to locate, understand, and update

Importing and Exporting Components

In order to use components defined in separate files, they must be imported and exported appropriately using ES6 module syntax.

// Button.js
import React, { Component } from 'react';

class Button extends Component {
  render() {
    return <button>{this.props.label}</button>;
  }
}

export default Button;
// Home.js
import React, { Component } from 'react';
import Button from '../components/Button';

class Home extends Component {
  render() {
    return (
      <div>
        <h1>Welcome to the Home Page</h1>
        <Button label="Click Me" />
      </div>
    );
  }
}

export default Home;

Reusability and Modularity

Separating components into individual files promotes reusability and modularity. Components can be easily shared and reused across different parts of the application, reducing duplication and enhancing code maintainability.

Encapsulation and Single Responsibility Principle

Each component file should ideally encapsulate a single component, adhering to the Single Responsibility Principle. This ensures that each component has a clear purpose and is responsible for a specific part of the UI.

React Class Component State

In React class components, state represents the data that a component can maintain and manipulate over time. State is initialized within the constructor using this.state, typically structured as an object where each key corresponds to a piece of mutable data. Components can access and modify their state using this.state and this.setState() respectively. It's crucial to update state immutably to ensure React can efficiently detect and reconcile changes. setState() is asynchronous, and React batches state updates for performance optimization. Additionally, functional setState allows for more precise state updates, especially when the new state depends on the previous state. As state changes, React automatically re-renders the component to reflect the updated state, ensuring the UI remains in sync with the underlying data. It's common practice to lift state up to the nearest common ancestor component when multiple components need access to the same state, promoting a unidirectional data flow and enhancing predictability in state management across the application. Understanding how to manage state effectively is essential for building dynamic and interactive user interfaces in React applications.

Creating the state Object

When it comes to creating the state object in React class components, there are several key considerations and practices to keep in mind.

Creating the State Object in React Class Components

  1. Initialization in the Constructor

    • In React class components, the state object is typically initialized within the constructor method.

    • The constructor method is a special method that gets called when an instance of the class is created

    •   class MyComponent extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              // Define state properties here
              count: 0,
              isLoggedIn: false,
              username: ''
            };
          }
        }
      
  2. Defining State Properties:

    • The state object is structured as a JavaScript object literal where each key-value pair represents a piece of state data.

    • State properties can include primitive types (such as numbers, booleans, and strings), as well as objects and arrays.

  3. Initializing State from Props:

    • It's common to initialize the state based on the props passed to the component.

    • You can assign initial values to state properties using props received by the component

    •   class UserProfile extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              username: props.username,
              email: props.email,
              isAdmin: props.isAdmin || false
            };
          }
        }
      
  4. Updating State Dynamically:

    • While the initial state is defined in the constructor, the state can be updated dynamically throughout the component's lifecycle using the setState() method.

    • setState() is used to modify the state object and triggers a re-render of the component with the updated state.

    •   handleIncrement() {
          this.setState({ count: this.state.count + 1 });
        }
      
  5. State Composition and Complexity:

    • State objects can become complex as the component grows and requires managing more stateful data.

    • It's essential to keep the state object concise and well-organized to maintain code readability and manageability.

  6. Considerations for Large State Objects:

    • As the state object grows in size, consider breaking it down into smaller, more manageable pieces.

    • Complex state logic can be encapsulated in separate objects or custom methods to keep the component class focused and maintainable.

  7. Default State Values:

    • You can provide default values for state properties using ES6 default parameter syntax or conditional logic within the constructor.

    •   class MyComponent extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              count: props.initialCount || 0,
              isLoggedIn: props.user ? true : false,
              // Other state properties...
            };
          }
        }
      

Using the state Object

Utilizing the state object in React class components is a fundamental aspect of building dynamic and interactive user interfaces

Using the State Object in React Class Components

  1. Accessing State:

    • Components can access state data using this.state.

    • State data is typically used within the component's render method to dynamically generate the UI based on the current state

    •   render() {
          return <div>{this.state.count}</div>;
        }
      
  2. Updating State

    • State should be updated using the setState() method provided by React.

    • setState() merges the provided object into the current state and triggers a re-render of the component with the updated state

    •   incrementCount() {
          this.setState({ count: this.state.count + 1 });
        }
      
  3. Asynchronous Nature of setState():

    • Calls to setState() are asynchronous for performance reasons.

    • React may batch multiple setState() calls into a single update for optimization purposes.

  4. Functional setState():

    • setState() can also accept a function as an argument, which receives the previous state and props as arguments.

    • This is useful when the new state depends on the previous state.

    •   incrementCount() {
          this.setState(prevState => ({
            count: prevState.count + 1
          }));
        }
      
  5. Immutable State Updates:

    • State should be treated as immutable in React. Directly mutating state can lead to unexpected behavior.

    • Always use setState() to update state, ensuring that React can detect and reconcile state changes correctly.

  6. Conditional Rendering Based on State:

    • Components can conditionally render UI elements based on the current state.

    • Conditional rendering allows components to adapt their output based on changes to the state.

    •   render() {
          return (
            <div>
              {this.state.isLoggedIn ? (
                <WelcomeMessage username={this.state.username} />
              ) : (
                <LoginPrompt />
              )}
            </div>
          );
        }
      
  7. Passing State as Props:

    • State data can be passed down to child components as props, enabling them to access and render stateful data.

    •   <ChildComponent count={this.state.count} />
      
  8. Using State to Control Component Behavior:

    • State can be used to control various aspects of component behavior, such as toggling visibility, managing form input, or tracking user interactions.

    •   handleChange(event) {
          this.setState({ inputValue: event.target.value });
        }
      

Changing the state Object

Changing the state object in React class components is a fundamental aspect of building dynamic user interfaces

Changing the State Object in React Class Components

  1. Using setState() Method

    • React class components provide the setState() method to update the state object.

    • setState() accepts an object containing the updated state properties as its argument.

    •   this.setState({ count: this.state.count + 1 });
      
  2. Functional setState():

    • setState() also accepts a function as an argument, which receives the previous state and props as arguments.

    • This is useful when the new state depends on the previous state.

    •   this.setState(prevState => ({
          count: prevState.count + 1
        }));
      
  3. Asynchronous Nature of setState():

    • Calls to setState() are asynchronous for performance reasons.

    • React may batch multiple setState() calls into a single update for optimization purposes.

  4. Immutability of State:

    • State should be treated as immutable in React. Directly mutating state can lead to unexpected behavior.

    • Always use setState() to update state, ensuring that React can detect and reconcile state changes correctly.

  5. Merging State Updates:

    • When using setState(), React automatically merges the provided object into the current state

    •   this.setState({ 
          user: {
            ...this.state.user,
            name: 'John'
          }
        });
      
  6. Updating Nested State Properties:

    • When updating nested state properties, it's essential to shallow copy the existing state object to maintain immutability

    •   this.setState(prevState => ({
          user: {
            ...prevState.user,
            address: {
              ...prevState.user.address,
              city: 'New York'
            }
          }
        }));
      
  7. Conditional State Updates:

    • State updates can be conditionally applied based on the current state or props

    •   if (this.state.count < 10) {
          this.setState({ count: this.state.count + 1 });
        }
      
  8. Using Previous State:

    • When updating state based on the current state, it's recommended to use the functional form of setState() to avoid race conditions.

    •   this.setState(prevState => ({
          count: prevState.count + 1
        }));
      
  9. Batching State Updates:

    • React may batch multiple setState() calls into a single update for performance optimization.

    •   this.setState({ count: this.state.count + 1 });
        this.setState({ count: this.state.count + 1 });
        // React may batch these updates into a single update
      

Lifecycle of Components

The lifecycle of React class components is a critical concept to understand for building robust and efficient applications. Here's a detailed overview of the component lifecycle along with explanations for each stage

Lifecycle of React Class Components

  1. Mounting Phase

    • constructor(): This is the first method called when a component is created. It's used for initializing state and binding event handlers.

    • static getDerivedStateFromProps(): This static method is called before rendering when new props or state are received. It's rarely used but can be useful for derived state based on props.

    • render(): This method is required and must return elements to be rendered on the screen. It's responsible for the component's UI.

    • componentDidMount(): This method is called after the component is rendered for the first time. It's commonly used for performing initial setup, such as fetching data from APIs or setting up subscriptions.

  2. Updating Phase

    • static getDerivedStateFromProps(): As mentioned earlier, this method is called before rendering when new props or state are received.

    • shouldComponentUpdate(): This method is called before rendering when new props or state are received. It determines if the component should re-render by returning a boolean value.

    • render(): Renders the updated UI based on the new props or state.

    • getSnapshotBeforeUpdate(): This method is called right before the changes from the Virtual DOM are to be reflected in the DOM. It allows the component to capture some information from the DOM before it is potentially changed.

    • componentDidUpdate(): This method is called after the component is updated in the DOM. It's commonly used for performing side effects, such as fetching data based on props changes or updating the DOM in response to prop or state changes.

  3. Unmounting Phase

    • componentWillUnmount(): This method is called just before the component is removed from the DOM. It's used for cleanup tasks, such as removing event listeners or cancelling network requests.

    •   class MyComponent extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              count: 0
            };
          }
      
          componentDidMount() {
            // Fetch initial data
            fetchData().then(data => {
              this.setState({ data });
            });
          }
      
          componentDidUpdate(prevProps, prevState) {
            if (prevState.count !== this.state.count) {
              // Perform some side effect based on state change
            }
          }
      
          componentWillUnmount() {
            // Clean up subscriptions or timers
            clearInterval(this.timer);
          }
      
          render() {
            return <div>{this.state.count}</div>;
          }
        }
      

Mounting

The mounting phase in React class components refers to the process of creating an instance of the component and inserting it into the DOM. It involves several lifecycle methods that allow developers to perform initialization tasks and set up the component before it is rendered for the first time

Mounting Phase in React Class Components

  1. constructor() Method:

    • The constructor() method is the first lifecycle method called when a component is instantiated.

    • It's used for initializing state, binding event handlers, and setting up initial values.

    •   class MyComponent extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              count: 0
            };
          }
        }
      
  2. render() Method:

    • The render() method is required in every React component.

    • It returns the JSX that defines the component's UI

    •   render() {
          return <div>{this.state.count}</div>;
        }
      
  3. componentDidMount() Method:

    • The componentDidMount() method is called immediately after the component is mounted (inserted into the DOM).

    • It's commonly used for performing side effects, such as data fetching, setting up subscriptions, or interacting with the DOM

    •   componentDidMount() {
          // Fetch initial data from an API
          fetchData().then(data => {
            this.setState({ data });
          });
        }
      
  4. Example of Mounting Phase:

    • In the following example, the MyComponent class demonstrates the mounting phase lifecycle methods

    •   class MyComponent extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              count: 0
            };
          }
      
          componentDidMount() {
            // Fetch initial data from an API
            fetchData().then(data => {
              this.setState({ data });
            });
          }
      
          render() {
            return <div>{this.state.count}</div>;
          }
        }
      
  5. Use Cases

    • Mounting phase lifecycle methods are commonly used for initialization tasks, such as setting up state, fetching data, initializing timers, and subscribing to external data sources.

    • They provide an opportunity to perform operations that require access to the DOM or external resources before the component is rendered

Updating

The updating phase in React class components occurs when a component's state or props change, triggering a re-render of the component and its children. This phase involves lifecycle methods that allow developers to control how the component reacts to changes and update its UI accordingly

Updating Phase in React Class Components

  1. static getDerivedStateFromProps() Method:

    • The static getDerivedStateFromProps(nextProps, prevState) method is called before every render when new props are received.

    • It allows the component to update its state based on changes in props.

    •   static getDerivedStateFromProps(nextProps, prevState) {
          if (nextProps.value !== prevState.value) {
            return { value: nextProps.value };
          }
          return null;
        }
      
  2. shouldComponentUpdate() Method

    • The shouldComponentUpdate(nextProps, nextState) method is called before rendering when new props or state are received.

    • It allows the component to determine if it should re-render by returning a boolean value

    •   shouldComponentUpdate(nextProps, nextState) {
          return nextProps.value !== this.props.value;
        }
      
  3. render() Method:

    • The render() method is required in every React component and returns the JSX that defines the component's UI.

    •   render() {
          return <div>{this.props.value}</div>;
        }
      
  4. getSnapshotBeforeUpdate() Method

    • The getSnapshotBeforeUpdate(prevProps, prevState) method is called right before the changes from the Virtual DOM are to be reflected in the DOM.

    • It allows the component to capture some information from the DOM before it is potentially changed.

    •   getSnapshotBeforeUpdate(prevProps, prevState) {
          if (prevProps.list.length < this.props.list.length) {
            return this.listRef.scrollHeight - this.listRef.scrollTop;
          }
          return null;
        }
      
  5. componentDidUpdate() Method:

    • The componentDidUpdate(prevProps, prevState, snapshot) method is called after the component is updated in the DOM.

    • It's commonly used for performing side effects, such as fetching data based on props changes or updating the DOM in response to prop or state changes.

    •   componentDidUpdate(prevProps, prevState, snapshot) {
          if (snapshot !== null) {
            this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;
          }
        }
      
  6. Example of Updating Phase

    • In the following example, the MyComponent class demonstrates the updating phase lifecycle methods.

    •   class MyComponent extends React.Component {
          static getDerivedStateFromProps(nextProps, prevState) {
            if (nextProps.value !== prevState.value) {
              return { value: nextProps.value };
            }
            return null;
          }
      
          shouldComponentUpdate(nextProps, nextState) {
            return nextProps.value !== this.props.value;
          }
      
          getSnapshotBeforeUpdate(prevProps, prevState) {
            if (prevProps.list.length < this.props.list.length) {
              return this.listRef.scrollHeight - this.listRef.scrollTop;
            }
            return null;
          }
      
          componentDidUpdate(prevProps, prevState, snapshot) {
            if (snapshot !== null) {
              this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;
            }
          }
      
          render() {
            return <div>{this.props.value}</div>;
          }
        }
      
  7. Use Cases

    • Updating phase lifecycle methods are commonly used for optimizing performance by preventing unnecessary re-renders (shouldComponentUpdate), handling side effects after updates (componentDidUpdate), and synchronizing state with props (getDerivedStateFromProps).

Unmounting

The unmounting phase in React class components occurs when a component is removed from the DOM. This phase involves a single lifecycle method that allows developers to perform cleanup tasks, such as clearing timers, unsubscribing from events, or cancelling network requests, before the component is destroyed.

Unmounting Phase in React Class Components

  1. componentWillUnmount() Method

    • The componentWillUnmount() method is called just before a component is unmounted and destroyed.

    • It's used for cleanup tasks, such as removing event listeners, clearing intervals or timeouts, or cancelling network requests.

    •   componentWillUnmount() {
          clearInterval(this.timer);
        }
      
  2. Example of Unmounting Phase

    • In the following example, the MyComponent class demonstrates the unmounting phase lifecycle method

    •   class MyComponent extends React.Component {
          componentDidMount() {
            this.timer = setInterval(() => {
              // Update state or perform other tasks
            }, 1000);
          }
      
          componentWillUnmount() {
            clearInterval(this.timer);
          }
      
          render() {
            return <div>{this.props.value}</div>;
          }
        }
      
  3. Use Cases

    • The componentWillUnmount() method is commonly used for cleanup tasks that need to be performed before a component is removed from the DOM.

    • It's essential for releasing resources, preventing memory leaks, and ensuring that the application remains efficient and responsive.

  4. Removing Event Listeners:

    • Components often attach event listeners during their lifecycle. It's crucial to remove these listeners in componentWillUnmount() to avoid memory leaks and unexpected behaviour.

    •   componentDidMount() {
          window.addEventListener('resize', this.handleResize);
        }
      
        componentWillUnmount() {
          window.removeEventListener('resize', this.handleResize);
        }
      
  5. Clearing Timers and Intervals:

    • Components may set up timers or intervals during their lifecycle. It's important to clear these timers in componentWillUnmount() to prevent memory leaks and unnecessary resource consumption.

    •   componentDidMount() {
          this.timer = setInterval(() => {
            // Update state or perform other tasks
          }, 1000);
        }
      
        componentWillUnmount() {
          clearInterval(this.timer);
        }
      
  6. Cancelling Network Requests:

    • Components may initiate network requests or subscriptions to external data sources. It's essential to cancel these requests or unsubscribe from data sources in componentWillUnmount() to prevent memory leaks and avoid unnecessary network traffic.

    •   componentDidMount() {
          this.subscription = dataStream.subscribe(this.updateData);
        }
      
        componentWillUnmount() {
          this.subscription.unsubscribe();
        }
      

Summary

React class components play a pivotal role in building dynamic and interactive user interfaces. Understanding their lifecycle is essential for effective component management and optimization. In this article, we explored the lifecycle phases of React class components:

  1. Mounting Phase:

    • Components are created and inserted into the DOM.

    • Lifecycle methods include constructor(), render(), and componentDidMount().

    • Used for initialization tasks and interacting with external data sources.

  2. Updating Phase:

    • Components are re-rendered in response to changes in state or props.

    • Lifecycle methods include static getDerivedStateFromProps(), shouldComponentUpdate(), render(), getSnapshotBeforeUpdate(), and componentDidUpdate().

    • Used for optimizing performance and handling side effects after updates.

  3. Unmounting Phase:

    • Components are removed from the DOM.

    • Lifecycle method is componentWillUnmount().

    • Used for cleanup tasks such as removing event listeners and clearing timers.

Understanding these lifecycle phases allows developers to manage components effectively, optimize performance, and prevent memory leaks. By leveraging lifecycle methods appropriately, developers can build robust and efficient React applications that provide a seamless user experience.