Lifecycle Methods in React

Developers can manage and alter components from the time of creation to the point of destruction with the help of React component lifecycle and hooks.

Lifecycle Methods in React
Lifecycle Methods in React - thetechfoyer, thetechfoyer.com
Lifecycle Methods in React

This Article helps you to Understand, Life Cycle Methods in React Js

React component lifecycle & Hooks give developers the ability to manage and modify components from the point of creation to the point of destruction.There are various methods in the react component lifecycle at various stages of a component's lifetime.



What is a component??
In React, a component is a building block for creating user interfaces. Components are reusable code segments that can be joined to produce a more complex user interface. A JavaScript function that returns a chunk of code (commonly referred to as JSX) that represents a portion of the user interface might be thought of as a component.

Class components and functional components are the two primary categories of components. Class components are more capable and have access to more capabilities, like lifecycle and state methods, whereas functional components are more straightforward and lightweight.


The React Component Lifecycle
Different stages of the component lifecycle and the methods associated with each stage.

The lifetime of a React component consists of three stages: mounting, updating, and unmounting.
However, when working with functional component state, you may now use abstracted versions of these lifecycle functions because React introduced the idea of hooks.
React Hooks are functions that let function components "hook into" React states and their lifecycle characteristics.



Lifecycle State

  • Initialization
  • Mounting
    • constructor()
    • static getDerivedStateFromProps()
    • render()
    • componentDidMount()
  • Updating
    • static getDerivedStateFromProps()
    • shouldComponentUpdate()
    • render()
    • getSnapshotBeforeUpdate()
    • componentDidUpdate()
  • Unmounting
    • componentWillUnmount()
  • Error Handling
    • static getDerivedStateFromError()
    • componentDidCatch()



How the Component Lifecycle Works
Components in React go through a lifecycle made up of various stages.
Each of these stages offers specific methods that you can customize to run your code at different points during a component's lifecycle.
Using these methods you can perform tasks such as initializing data, managing updates, and tidying up resources as needed.



Class Component Lifecycle Methods

constructor:-
When a component is created, the constructor method is the first to be called. It is used to initialize the component’s state and bind event handlers

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

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

render() {
  return (
      <div>
          <p>You clicked {this.state.count} times</p>
          <button onClick={this.handleClick}>Click me</button>
      </div>
  );
}



getDerivedStateFromProps:-
This method is called right after the constructor and just before rendering the element in our DOM, allowing the component to update its state based on changes to its props.
It takes props and state as an argument and should return an object (with changes to the state) to update the state or null if no update is needed.

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

// ============== OR
static getDerivedStateFromProps(props, state) {
  return { name: props.nameFromParent }
}



shouldComponentUpdate:-

This method is called before the component is updated, allowing the component to determine whether it should re-render. It should return a boolean value indicating whether the component should update or not.

it gives you option to tell React when you don't need to re-render when a new state or props comes in. While it can help avoid re-renders, you shouldn’t rely on it to prevent re-renders since you might skip a necessary update and encounter bugs. 

shouldComponentUpdate(nextProps, nextState) {
  // Rendering the component only if  
  // passed props value is changed
  return nextProps.value !== this.props.value;
}

// ============== OR
shouldComponentUpdate(nextProps, nextState) {
  // Allow the component to re-render only
  // if the count is greater than 20
  if (nextState.count > 20) {
      return true; // Re-render
  }
  return false; // Don't re-render
}



render:-

This method is responsible for rendering the component’s UI.It should return a React element, a JSX expression, or a call to React.createElement(). This method is responsible to render our JSX to DOM. The render() method is the only required method in a class component.

render() {
  return <div>Hello, {this.props.name}!</div>;
}

//-- OR

render() { return null; }



getSnapshotBeforeUpdate: -

This method is called just before the component is updated and allows the component to capture some information from the DOM before it changes. This information is then passed to componentDidUpdate().

getSnapshotBeforeUpdate() becomes meaningless if the parameter(snapshot) is not used in componentDidUpdate(), and it could be unintended.

getSnapshotBeforeUpdate(prevProps, prevState) {
  if (prevProps.value !== this.props.value) {
      return this.myRef.current.getBoundingClientRect().top;
  }
  return null;
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot !== null) {
      console.log(`Element was ${snapshot}px from the top`);
  }
}

//========== OR
constructor(props) {
  super(props);
  this.state = { msg: 'welcome' };
  this.handleClick = this.handleClick.bind(this);
  this.helloRef = React.createRef();
}

getSnapshotBeforeUpdate(prevProps, prevState) {
  if (prevState.msg !== this.state.msg) {
      const hello = this.helloRef.current;
      return hello.offsetLeft;
  }
  return null;
}

handleClick() {
  if (this.state.msg === 'welcome') {
      this.setState({ msg: 'good bye' });
  } else {
      this.setState({ msg: 'welcome' });
  }
}
render() {
  return
      <div
          ref={this.helloRef}
          onClick={this.handleClick}
          style={{ position: "absolute" }}>
              {this.state.msg}
      </div>;
}



componentDidMount:-

componentDidMount is called after a component has been added to the DOM.
It's an excellent location to carry out initial setup operations, such as fetching data from an API or configuring event listeners.
In the constructor, the component's state is initialized with data set to blank arary. We use this array to store the fetched data from our backend

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

export class Employee extends Component {
    constructor(props) {
        super(props);
        this.state = {
            employees: [],
        }
    }
    componentDidMount() {
        fetch(variables.API_URL + 'employee/GetEmployee')
            .then(response => response.json())
            .then(data => {
                console.log(data);
                this.setState({ employees: data });
            });
    }
}



componentDidUpdate:-

The componentDidUpdate method is the last lifecycle method invoked in the update phase.
componentDidUpdate is called after a component has re-rendered as a result of modifications to its state or props and not at the initial render.
It's an excellent location to manage side, such as updating the DOM or dispatching an action to a Redux store or take further action in response to those modifications, like sending network requests or calling the this.setState method.
This method can accept up to three parameters: prevProps, prevState, and snapshot.

componentDidUpdate(prevProps, prevState) {
  if (prevProps.value !== this.props.value) {
      // Refresh - Refetch data
  }
}

componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot !== null) {
   // Refresh - Refetch data
 }
}



componentWillUnmount:-

componentWillUnmount is called just before a component is removed from the DOM (unmounts & destroyed ).
It is an essential place for cleaning tasks, like unsubscribing from events, clearing timers, canceling API calls, clearing any data structures and releasing resources to stop memory leaks.
After componentWillUnmount() is called, the component is removed from the DOM and all of its state and props are destroyed.

componentDidMount() {
  this.timer = setTimeout(() => {
      this.setState({
          title: "Welcome to React Lifecycle!"
      });
  }, 1000);
} // the title will be changed in 1 sec.
componentWillUnmount() {
  console.log("unmounting begins...");
  clearTimeout(this.timer);
}

//=========== OR =======================================

constructor(props) {
  super(props);
  this.state = {};
  this.openMenu = this.openMenu.bind(this);
  this.closeMenu = this.closeMenu.bind(this);
}
componentDidMount() {
  document.addEventListener("click", this.closeMenu);
}
componentWillUnmount() {
  document.removeEventListener("click", this.closeMenu);
}
openMenu() {
}
closeMenu() {
}


A few lifecycle methods were deprecated in the React version 16.3.0:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate


React Hooks
In React 16.8, hooks were introduced. Without designing class components, they allowed functional components to access state and other React capabilities.
Hooks were added to React code to address several issues and make React code easier to understand and maintain:-

  • Complexity – class components can become complex when managing state and side effects.
  • Reusability – logic in class components isn't easily shareable between components.