React Component Lifecycle Methods from v16.3 with example

From v16.3, React introduces new 2 lifecycles getDerivedStateFromProps, getSnapshotBeforeUpdate, and also notices that 3 methods will be in time considered deprecation componentWillMount, componentWillUpdate, componentWillReceiveProps. In this tutorial, we’re gonna look at new React Component Lifecycle Methods, then we will build an example that uses them.

Component Lifecycle

Mounting methods

constructor()

This method will be called whenever a new object is created. super(props) calls the constructor of parent class (React.Component) to initialize itself. Now we have access to this.props.

constructor() is used for setting up Component such as creating class fields or initialize state by directly overwriting the this.state. Don’t call this.setState() here.

It is also often used to bind functions that will be passed as callbacks.

1

2

3

4

5

6

7

8

9

10

constructor(props){

super(props);

this.add=this.add.bind(this);

this.minus=this.minus.bind(this);

this.state={

counter:0,

anotherCounter:props.initialCounter

}

}

Don’t make any side effects (AJAX call for example) or subscription in the constructor. Use componentDidMount() instead.

static getDerivedStateFromProps()

This method is invoked after a Component is instantiated as well as when it receives new props.

Static method doesn’t exist on instance, but the class. So it does not have access to this keyword. It helps us NOT call this.setState() here, instead we should return an object to update state, or null if no update is needed (only need to return the part of state that changes, other will be preserved).

*Note:
– If parent Component causes this Component to re-render, this method will be called even if props have not changed => compare new and previous values if we want to handle changes.

– Calling this.setState() doesn’t trigger getDerivedStateFromProps().

1

2

3

4

5

6

7

8

9

10

11

staticgetDerivedStateFromProps(nextProps,prevState){

if(prevState.counter>nextProps.maxCount){

console.log('set counter to ['+nextProps.maxCount+']');

return{

counter:nextProps.maxCount

};

}

console.log('check MAX counter >> no need to change counter!');

returnnull;

}

render()

This method is required.

When render() is called, it analyses this.props and this.state and return React elements (native DOM Component or a user-defined composite Component), String or number, Portal, null or Boolean (render nothing).

render() should not modify component state or directly interact with the browser. If you need to interact with the browser, use componentDidMount() or the other lifecycle methods instead.

*Note:: render() will not be invoked if shouldComponentUpdate() returns false.

1

2

3

4

5

6

7

8

9

10

11

render(){

return(

<div>

<h1>Java Sample Approach</h1>

<h3>{this.props.maxCount}</h3>

<p>Counter: {this.state.counter}</p>

<button onClick={this.add}>ADD+</button>

<CalculatorComponent />

</div>

);

}

componentDidMount()

This method is guaranteed to be called only once in the whole lifecycle , immediately after a component is mounted.

It is good for performing any side-effect causing operations such as AJAX requests or set up subscription. Calling this.setState() is not recommended, but for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position. We also use componentDidMount() to load the data which is saved to localStorage.

1

2

3

4

5

6

7

8

9

10

11

12

componentDidMount(){

// load saved data

conststrCount=localStorage.getItem('counter');

constcounter=Number.parseInt(strCount,10);

if(!isNaN(counter)){

if(counter>this.props.maxCount){

counter=this.props.maxCount;

}

this.setState(()=>({counter}));

}

}

Updating methods

static getDerivedStateFromProps()

This method will be invoked when Component receives new props. We have described getDerivedStateFromProps() before.

shouldComponentUpdate()

This method will be called internally when new props or state are being received. We can use shouldComponentUpdate() to verify that the change requires a re-render or not:
– return false to prevent the re-rendering the component (it does not prevent child components from re-rendering when their state changes).
– in other cases, return true (defaults to true).

*Note:
– It is not recommended to make deep equality checks or cause any side effects (such as AJAX calls or using JSON.stringify()) for performance.
– Don’t call this.setState().

1

2

3

4

5

6

7

8

9

shouldComponentUpdate(nextProps,nextState){

if(nextState.counter>nextProps.maxCount){

// not update component

returnfalse;

}

// update component

returntrue;

}

render()

This method will be called if shouldComponentUpdate() returns true.

getSnapshotBeforeUpdate()

This method is invoked right before right before mutations are made (for example, before the DOM is updated). We can capture current values before they are potential changed. Returned value of getSnapshotBeforeUpdate() will be passed as the third parameter to componentDidUpdate().

componentDidUpdate()

This method is invoked immediately after finish of render() method, in each of the re-render cycles. In the initial render, it is not be called.

Use this to make side effects (AJAX calls, network requests for example) or save data/state to localStorage. We should compare the current props/state to previous props/state to make sure that it is necessary.

*Note:
– componentDidUpdate() will not be invoked if shouldComponentUpdate() returns false.
– third parameter snapshot is passed from the return value of getSnapshotBeforeUpdate(). (default to undefined).
– try not to call this.setState() here.

1

2

3

4

5

6

componentDidUpdate(prevProps,prevState,snapshot){

if(prevState.counter!==this.state.counter){

// save counter value to storage

localStorage.setItem('counter',this.state.counter);

}

}

Unmounting methods

componentWillUnmount()

This method is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount().

We can clean up and perform any operation to remove/close things no longer needed, such as timers, listeners, network requests, or subscriptions.

Don’t call this.setState() or start new listeners, timers or make any request.

Error Handling method

componentDidCatch()

This method helps parent component to capture an unhandled errors happening in the child components and display a fallback UI.

*Note:
– Only use error boundaries for recovering from unexpected exceptions; don’t try to use them for control flow.
– Error boundaries only catch errors in the child components, but not within itself.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

classMyComponent extendsReact.Component{

constructor(props){

super(props);

this.state={

hasError:false

};

}

componentDidCatch(error,info){

// fallback UI

this.setState({hasError:true});

logError(error,info);

}

render(){

if(this.state.hasError){

// render custom fallback UI

return<h1>Error in...</h1>;

}

return(

// normal component

);

}

}

componentDidCatch(error, info)
– error: .toString() of the error
– info: an object represents the stack trace back to where the error occured

Practice

Example Overview

We will build a React application which:
– has Counter that can increase/decrease by ADD/MINUS button.
– has MaxCount that limited the Counter: when Counter get equal to MaxCount, displayed Counter value can not increase anymore (but real Counter value still increases).
– can update MaxCount by button, it will increase MaxCount by 1. If real Counter value is bigger than MaxCount, it will be equal to MaxCount.

grokonez

ABOUT US
We are passionate engineers in software development by Java Technology & Spring Framework. We believe that creating little good thing with specific orientation everyday can make great influence on the world someday.