A component goes through various states before being and rendered. These different states through which a component passes in its entire journey is called Component Lifecycle. Each state of a component is defined by a method which is called automatically by react when that state is reached.
Complete component lifecycle can be divided into 4 phases
A. Initialization: In this phase, state
and props
objects of the component are prepared and populated. Method that is invoked in this phase is the constructor.
B. Mounting: Instance of the component is created and inserted into DOM in this phase. Methods that are invoked in this phase are componentWillMount
, render
and componentDidMount
.
C. Updation: After the component is rendered, if its state is changed or props is updated, this phase comes into action. Methods that are invoked in this phase are shouldComponentUpdate
.
D. Unmounting: When a component is removed from the DOM(usually when the page is changed or it is hidden dur to an event), this phase is called Unmounting. The only method that is executed in this phase is componentWillUnmount
.
Component lifecycle methods are only applicable to stateful components or the components which are created as classes extending React.Component.
Lifecycle Methods
A detailed discussion on all lifecycle methods follows.
1. constructor()
A constructor is a special method that is called when an object(or instance) of a class is created. This applies to every programming language and react too. A constructor is react is created using constructor
function. It receives props
object as argument. You should make a call to parent class constructor by calling super
with props
as argument as the first line in the constructor. If this is not done, the application will raise an error ReferenceError: this hasn’t been initialised – super() hasn’t been called.
A constructor is not required in every component class. It is only required when
i. You want to create and initialize state
for the component.
ii. Event handlers need to be bound to the component instance.
You can initialize state object directly inside constructor only. Outside the constructor, you need to call setState
method to modify state object.
2. componentWillMount()
This method is called just before the component is mounted. It is called once in the lifecycle and after component’s constructor. It is not recommended to use this method. Any initialization that needs to be performed should be done inside constructor. This method is called once for a component before render
method or just before the component is being rendered. Calling setState
method in this method will not re-render the component and hence, any state initialization should be performed inside the constructor only.
UNSAFE_componentWillMount()
.3. render()
This is the only required method in a component. It is responsible for displaying elements on the screen. It can return following value types:
i. React elements: Elements to be rendered on the screen in the form of JSX.
ii. Fragments: Fragment lets you return multiple elements from render
method without adding an extra element to the DOM.
iii. String: You can also return a string from render
method. It is displayed as text on the screen.
iv. Boolean or null: When any of these values is returned, nothing is rendered on the screen. Boolean is generally used to return JSX expression. Refer Conditional rendering section to understand more on this.
render method should not modify the component state in any way. It should return the same value when invoked multiple times.
4. componentDidMount()
This method is called after the component has been mounted, that is, after the render
method completes. It is executed once in the lifecycle of the component. Any initialization activities should be performed in this method. Since this method is called after the component has been inserted into the DOM, you can also access DOM nodes here. Any third party library should be initialized here and any remote call that fetches data should be performed here.
You can also call setState
from this method. Calling setState
will re-render the component causing its render
method to be called once again.
5. shouldComponentUpdate()
This method is called if componentDidMount
changes the state or props object. It may or may not receive arguments. If it receives arguments, then they are the new state
and props
objects. Thus, if the initial state
object had a property named ‘technology’ with value ‘Reactv16’ and componentDidMount
changed it to ‘Reactv17’ by calling setState
method, then shouldComponentUpdate
will receive state object with updated value of ‘technology’.
This method should return either true
or false
which denotes whether the component should be re-rendered or not. If it returns true
, then render
will be called again else not.
6. componentWillUpdate()
This method is executed only if shouldComponentUpdate
returns true
. It is called before render
method is invoked once again. This method may also receive new state
and props
objects as arguments. You cannot call setState
method from this method else you will get an error Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.
UNSAFE_componentWillUpdate()
.7. componentDidUpdate()
This method is called after the component update is complete and is called only when
i. state
or props
is modified from componentDidMount
method and,
ii. shouldComponentUpdate
method returns true
. If this method is not present, then also componentDidUpdate
method is called but condition (i) should be satisfied.
8. componentWillUnmount()
This method is called before the component is unmounted or destroyed. This is the last method in the lifecycle of a component. This method should be used for performing cleanup tasks such as clearing timer objects, removing any subscriptions etc.
You should not call setState
from this method as it will serve no purpose since the component will never be re-rendered again.
All the methods are executed in the same order as defined above. Example given below shows this.
import React, {Component} from 'react'; import ReactDOM from 'react-dom'; // create component class LifecycleDemo extends Component { constructor(props) { super(props); this.state = { name:'python' }; } componentWillMount() { console.log("Component will mount"); } componentDidMount(){ this.setState({name:'react'}); console.log("Component did mount"); } shouldComponentUpdate(){ console.log("Should Component update"); return true; } componentWillUpdate() { console.log("Component will update") } componentDidUpdate() { console.log("Component did update"); } componentWillUnmount() { console.log("Component will unmount") } render() { console.log("Render"); return ( <div> Lifecycle </div>); } } // attach ReactDOM.render(<LifecycleDemo />, document.getElementById('root'));
This example produces below output
Component will mount
Render
Component did mount
Should Component update
Component will update
Render
Component did update
Above output shows the order in which the methods are executed. Note that render
method is executed twice. This is because we are modifying state
in componentDidMount
method.
If you do not modify state using setState
method in componentDidMount
method, the output is
Component will mount
Render
Component did mount
which shows that render
method is not called again if the state
is not modified.
Now even if you modify state in componentDidMount
method but return false
from shouldComponentUpdate
, then also render
is not called again and below output confirms this.
Component will mount
Render
Component did mount
Should Component update
To conclude, just remember that lifecycle methods are supported only for class based components. Out of all lifecycle methods, a component should have render
method.