ReactJS – Component Life Cycle In Depth

Just like every other lifecycle, React Component Lifecycle is also a loop. It starts with creating it, then mounting it on the DOM and unmounting it when it’s destroyed. This is what React Component Lifecycle actually is!

The beauty of React is that it provides ‘hooks.’ These are the methods that get called automatically at each stage of the lifecycle. A good know-how of these hooks gives the ability to efficiently control and manipulate what goes on in a component throughout its lifetime.

A React Component can go through four stages of its life as follows.

  • Initialization: This is the stage where the component is constructed with the given Props and default state. This is done in the constructor of a Component Class.
  • Mounting: Mounting is the stage of rendering the JSX returned by the render method itself.
  • Updating: Updating is the stage when the state of a component is updated and the application is repainted.
  • Unmounting: As the name suggests Unmounting is the final step of the component lifecycle where the component is removed from the page.

What is lifecycle methods and why it is important?

Around us everything goes through a cycle of taking birth, growing and at some point of time it will die. Consider trees, any software application, yourself, a div container or UI component in a web browser, each of these takes birth, grows by getting updates and dies.

The lifecycle methods are various methods which are invoked at different phases of the lifecycle of a component. Suppose if we are creating the YouTube app, then obviously our app will use the network to buffer the videos and it spends the battery power (let’s assume only these two).
If the user switches to another application after playing the video, then being the awesome developers, we should make sure we are using the resources like network and battery in the most efficient manner. Whenever the user switches to another application, we can stop/pause the buffering of the video, which will stop using the network and battery.

This is what the lifecycle methods in ReactJs provide us, so that the developer can produce a quality application and make sure the developer can really plan what and how to do at various points of birth, growth or death of UI interfaces.

So what is gone in React 17

The lifecycle methods below has been deprecated. in React 17

componentWillMount
componentWillRecieveProps
componentWillUpdate

The above lifecycle methods are categorized as unsafe in the 16.3 release. Deprecation warnings will be added to the legacy methods in the release after that. Finally, the legacy methods has been deprecated completely in React 17.

Interestingly, the unsafe methods are still been in use in React 17.

What is new?

The three old lifecycle methods are going to be renamed and two additional methods will be introduced as well.

UNSAFE_componentWillMount
UNSAFE_componentWillRecieveProps
UNSAFE_componentWillUpdate
getDerivedStateFromProps
getSnapshotBeforeUpdate

So the methods are not really gone, but they are marked unsafe. Programmers should be aware not to use them at all or sparingly use them with caution.

Async rendering will cause componentWillMount to trigger multiple rendering of your component tree. This makes it unsafe.

 

LifeCycle Methods –

MOUNTING :

1. CONSTRUCTOR

If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.

The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.

Typically, in React constructors are only used for two purposes:

You should not call setState() in the constructor(). Instead, if your component needs to use local state, assign the initial state to this.state directly in the constructor:

constructor(props) {
  super(props);
  // Don't call this.setState() here!
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}

Constructor is the only place where you should assign this.state directly. In all other methods, you need to use this.setState() instead. There is an awsome depth tutorial is given over here 

2. COMPONENTDIDMOUNT() METHOD

As the name suggests, after all the elements of the page is rendered correctly, this method is called. After the markup is set on the page, this technique called by React itself to either fetch the data from An External API or perform some unique operations which need the JSXelements.

componentDidMount() method is the perfect place, where we can call the setState() method to change the state of our application and render() the updated data loaded JSX. For example, we are going to fetch any data from an API then API call should be placed in this lifecycle method, and then we get the response, we can call the setState() method and render the element with updated data.

import React, { Component } from 'react';

class App extends Component {

  constructor(props){
    super(props);
    this.state = {
      data: 'Jordan Belfort'
    }
  }

  getData(){
    setTimeout(() => {
      console.log('Our data is fetched');
      this.setState({
        data: 'Hello WallStreet'
      })
    }, 1000)
  }

  componentDidMount(){
    this.getData();
  }

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

export default App;

If you see an above example, then I have simulated an API call with setTimeOut function and fetch the data. So, after the component is rendered correctly, componentDidMount() function is called and that call getData() function.

componentDidMount is useful if you want to use some non-React JavaScript plugins. For example, there is a lack of a good date picker in React. Pickaday is beautiful and it just plain works out of the box. So my DateRangeInput component is now using Pickaday for the start and end date input and I hooked it up like so:

  componentDidMount: function() {
    new Pikaday({
      field: React.findDOMNode(this.refs.start),
      format: 'MM/DD/YYYY',
      onSelect: this.onChangeStart
    });

    new Pikaday({
      field: React.findDOMNode(this.refs.end),
      format: 'MM/DD/YYYY',
      onSelect: this.onChangeEnd
    });
  },

The DOM needs to be rendered for Pikaday to hook up to it and the componentDidMount hook lets you hook into that exact event.

3.  static getDerivedStateFromProps()

The new method works a bit differently:

class List extends React.Component {
  static getDerivedStateFromProps(props, state) {
    if (props.selected !== state.selected) {
      return {
        selected: props.selected,
      };
    }

    // Return null if the state hasn't changed
    return null;
  }

  // ...
}

Instead of calling setState like in the first example, getDerivedStateFromPropssimply returns an object containing the updated state. Notice that the function has no side-effects; this is intentional.

getDerivedStateFromProps may be called multiple times for a single update, so it’s important to avoid any side-effects. Instead, you should use componentDidUpdate, which executes only once after the component updates.

Here’s our final code:

class List extends React.Component {
  static getDerivedStateFromProps(props, state) {
    if (props.selected !== state.selected) {
      return {
        selected: props.selected,
      };
    }

    // Return null if the state hasn't changed
    return null;
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.selected !== prevProps.selected) {
      this.selectNew();
    }
  }

  // ...
}

Wrapping Up

getDerivedStateFromProps improves on the older method by providing a function whose only purpose is to update the state based on prop changes, without any side effects. This makes the component as a whole much easier to reason about.

However, derived state adds some complexity to components, and it’s often completely unnecessary. Check out the post You Probably Don’t Need Derived State for alternatives.

For detail information click here 

 

4. RENDER ()

we will discuss about this in Next section.

 

 

UPDATING

1. RENDER ()

As React developers, the render() method is the most familiar. We create Elements (generally via JSX) and return them. We access the Component this.props and this.state and let these values derive how content should be generated. When we access this.state, any changes we made during componentWillMount() are fully applied.

Unlike any other method in the Life Cycle, render() is the one method that exists across multiple life cycle phases. It occurs here in Birth and it is where we spend a lot of time in Growth.

In both cases, we have the core principle of keeping render() a pure method. What does that mean? That means we shouldn’t call setState(), query the Native UI or anything else that can mutate the existing state of the application. The reason why is if we do this kind of interaction in render(), then it will kickoff another render pass. Which once again, triggers render() which then does the same thing… infinitely.

The React development mode1 is generally great at catching these kinds of errors and will yell at you if you do them. For example, if we did something silly like this

render() {
  // BAD: Do not do this!
  this.setState({ foo: 'bar' });
  return (
    <div className={ classNames('person', this.state.mode) }>
      { this.props.name } (age: { this.props.age })
    </div>
  );
}

React would log out the following statement:

Warning: setState(…): Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.

2. static getDerivedStateFromProps()

static getDerivedStateFromProps(props, state)

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.

This method exists for rare use cases where the state depends on changes in props over time. For example, it might be handy for implementing a <Transition> component that compares its previous and next children to decide which of them to animate in and out.

Deriving state leads to verbose code and makes your components difficult to think about.
Make sure you’re familiar with simpler alternatives:

This method doesn’t have access to the component instance. If you’d like, you can reuse some code between getDerivedStateFromProps() and the other class methods by extracting pure functions of the component props and state outside the class definition.

Note that this method is fired on every render, regardless of the cause. This is in contrast to UNSAFE_componentWillReceiveProps, which only fires when the parent causes a re-render and not as a result of a local setState.

 

continue to next section

 

source : https://reactjs.org/docs/