REACT

Component LifeCycle


Component lifecycle methods are a series of events that happen at different stages of a component's existence, from its creation to its destruction. Understanding these lifecycle methods is crucial for managing state, side effects, and rendering in a React application. Here is an overview of the React component lifecycle for both class components and functional components using hooks:

 

1. Initial Phase

It is the birth phase of the lifecycle of a ReactJS component. Here, the component starts its journey on a way to the DOM. In this phase, a component contains the default Props and initial State. These default properties are done in the constructor of a component. The initial phase only occurs once and consists of the following methods.

 

getDefaultProps()
It is used to specify the default value of this.props. It is invoked before the creation of the component or any props from the parent is passed into it. It used in older versions of React (before React 16).

 

Example:

class MyComponent extends React.Component {
 render() {
   return (
     <div>{this.props.someProp}</div>
   );
 }
}
MyComponent.defaultProps = {
 someProp: 'default value'
};

 

  • getInitialState()
    It is used to specify the default value of this.state. It is invoked before the creation of the component. It used in older versions of React (before React 16).

Example:

import React, { Component } from 'react';
class MyComponent extends Component {
 constructor(props) {
   super(props);
   this.state = {
     count: 0
   };
 }
 render() {
   return (
     <div>{this.state.count}</div>
   );
 }
}
export default MyComponent;

 

  • constructor()
    1. Called before the component is mounted.
    2. Used for initializing state and binding methods.

 

Example:

constructor(props) {
 super(props);
 this.state = {
   count: 0,
 };
}


2. Mounting (Initialization)

This phase occurs when the component is being inserted into the DOM.

 

  • static getDerivedStateFromProps() 
    1. Called right before rendering, both on the initial mount and on subsequent updates.
    2. Used to update state based on props.

 

Example:

static getDerivedStateFromProps(nextProps, prevState) {
 if (nextProps.someValue !== prevState.someValue) {
   return { someValue: nextProps.someValue };
 }
 return null;
}

 

  • render()
    1. The only required method in a class component.
    2. Returns the React elements to render to the DOM.

 

  • componentDidMount() 
    1. Called immediately after the component is mounted.
    2. Ideal for making API calls, setting up subscriptions, or other side effects.

 

Example:

componentDidMount() {
 fetch('/api/data')
   .then(response => response.json())
   .then(data => this.setState({ data }));
}

 

3. Updating (State or Props Changes)

 

  • static getDerivedStateFromProps()
    It is used to update the state based on changes in props before rendering. This method is static, meaning it does not have access to this or the component instance.

 

  • shouldComponentUpdate()

1. Called before re-rendering when new props or state are received.
2. Used to let React know if a re-render is necessary. Returns true or false.

 

Example:

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

 

  • render()
    Returns the React elements to be rendered to the DOM.

 

Example:

render() {
 return <div>{this.state.someValue}</div>;
}

 

  • getSnapshotBeforeUpdate()
    1. Called right before the DOM updates.
    2. Returns a value (snapshot) that will be passed to componentDidUpdate.

 

Example:

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

 

  • componentDidUpdate()

1. Called immediately after the component updates.

2. Used for working with the DOM after changes and making network requests based on the old props or state.

 

Example:

componentDidUpdate(prevProps, prevState, snapshot) {
 if (snapshot !== null) {
   const list = this.listRef.current;
   list.scrollTop = list.scrollHeight - snapshot;
 }
}

 

4. Unmounting (Component Removal)

  • componentWillUnmount()
    1. Called right before the component is unmounted and destroyed.
    2. Ideal for cleanup tasks like removing event listeners or canceling network requests.

 

Example:

componentWillUnmount() {
 clearInterval(this.timerID);
}

5. Error Handling

static getDerivedStateFromError()
1. Called when a descendant component throws an error.
2. Used to update state to display an error message.

 

componentDidCatch()

1. Called after an error has been thrown by a descendant component.
2. Used for logging error information.

 

Example:

Timer Component with Lifecycle Methods:

import React, { Component } from 'react';
class Timer extends Component {
 constructor(props) {
   super(props);
   this.state = {
     time: props.start,
     running: true,
   };
   this.timerID = null;
 }
 // Static method to update state based on props changes
 static getDerivedStateFromProps(nextProps, prevState) {
   if (nextProps.start !== prevState.time && prevState.running === false) {
     return { time: nextProps.start };
   }
   return null;
 }
 // Start the timer when the component mounts
 componentDidMount() {
   this.startTimer();
 }
 // Decide whether the component should re-render
 shouldComponentUpdate(nextProps, nextState) {
   // Only update if time or running state changes
   return nextState.time !== this.state.time || nextState.running !== this.state.running;
 }
 // Capture some information from the DOM before updates are made
 getSnapshotBeforeUpdate(prevProps, prevState) {
   if (prevState.time !== this.state.time) {
     return { prevTime: prevState.time };
   }
   return null;
 }
 // Use the snapshot value to perform some action after the update
 componentDidUpdate(prevProps, prevState, snapshot) {
   if (snapshot !== null) {
     console.log(`Time updated from ${snapshot.prevTime} to ${this.state.time}`);
   }
 }
 // Clean up when the component unmounts
 componentWillUnmount() {
   this.stopTimer();
 }
 // Start the timer
 startTimer = () => {
   this.timerID = setInterval(() => {
     this.setState((prevState) => ({ time: prevState.time + 1 }));
   }, 1000);
 };
 // Stop the timer
 stopTimer = () => {
   clearInterval(this.timerID);
   this.setState({ running: false });
 };
 render() {
   return (
     <div>
       <h1>Timer: {this.state.time}</h1>
       {this.state.running ? (
         <button onClick={this.stopTimer}>Stop</button>
       ) : (
         <button onClick={this.startTimer}>Start</button>
       )}
     </div>
   );
 }
}
export default Timer;