What is React lifecycle
A component goes through many different stages from the moment it is created till it is removed. Since our UI is dynamic, to respond to those ever-changing conditions React has given has methods so that we are able to track those changes and therefore respond to them appropriately. In this post, I will cover 4 of them: render
, componentDidMount
, componentDidUpdate
and shouldComponentUpdate
render
The job of render
is to return whatever markup you have written inside of it. Whenever the state of a component changes it will cause the render method to be called again thus the user is able to see the updated content. We use setState
to change the state of a component which makes React update the component to reflect the changes and thus call the render method again.
simple example of render
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
}
}
handleButtonClick = (event) => {
this.setState({
counter: this.state.counter + 1,
});
}
render() {
return (
<>
<h1>{`Counter: ${this.state.counter}`}</h1>
<button onClick={this.handleButtonClick}>Click me</button>
</>
);
}
}
The above code will display a button that changes the state of the counter
, and after every click render will be called again because React detected the change in state. So, we will see the updated counter
value whenever we click the button thanks to the render
function being called again.
Few things to note about render function is that:
- A class component must have a render method, think of this as kind of a contract you make with React you must follow whenever you create a class that extends
React.Component
. - You must not call
setState
directly inside the render function as React will detect a change which will cause a re-render which will detectsetState
and cause re-render again and so on and on which makes your app go in an infinite loop and crash.
componentDidMount
The componentDidMount
method is called just once when the component is inserted into the DOM. It is typically used to make API requests and set the initial state or initiailze state which requires DOM nodes.
example of componentDidMount
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
productsOnSale: []
}
}
getDailyDealsData() {
// API request to get data about what products are on sale
this.setState({
productsOnSale: data, // data from API about what products are on sale
});
}
componentDidMount() {
this.getDailyDealsData();
}
render() {
return (
<>
<h1>Daily Deals</h1>
<p>{this.state.productsOnSale}</p>
</>
);
}
}
Think of the case when you go to the homepage of an e-commerce site like Amazon and you see the daily deals section first. You as a user didn't interact with the website yet but you still see a deals section when the page got loaded. The above code tries to simulate that.
So above example first initializes an empty productsOnSale
array through the constructor and when the component is inserted into DOM it makes an API request through getDailyDealsData
function which will update the state of productsOnSale
and render that data to the browser.
We only need to fetch information about daily deals once at the start when you first load the page and this is a practical example where componentDidMount
can be used.
componentDidUpdate
The componentDidUpdate
method gets called whenever the component gets updated, but it is not called for the initial render unlike componentDidMount
however, it may run more than once. Let's take an example and try to understand it.
example of componentDidUpdate
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
}
}
handleButtonClick = (event) => {
this.setState({
counter: this.state.counter + 1,
});
}
// ----new function------
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("Component updated");
}
render() {
return (
<>
<h1>{`Counter: ${this.state.counter}`}</h1>
<button onClick={this.handleButtonClick}>Click me</button>
{console.log("render")}
</>
);
}
}
The above example is similar to the one in render
example but here we have defined an extra method componentDidUpdate
which gets called whenever the component updates. We are changing the value of counter
whenever the button is clicked hence this is causing the componentDidUpate
to run and log in to the console "Component updated".
Also, note that when you load the app for the first time and check the console, there is no "Component updated", it will only run after the initial render.
You might have noticed that componentDidUpdate
also has some parameters, I will explain their usage below.
another componentDidUpdate example
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevState.searchTerm !== this.state.searchTerm) {
// make API request
this.searchVideos(this.state.searchTerm);
}
}
Suppose you are using youtube to search for videos. You searched for "React tutorials" and got the results, then you cleared the input and searched for "React tutorial" again, youtube can opt to not make the same search request again as that would be a waste and thus there will be no update to the component. We can do this like in the example above, we are comparing prevState
with the current state
and if there are different search terms, then only make the API request.
shouldComponentUpdate
The shouldComponentUpdate
dictates whether the component will get updated or not. We can return true
if we want the component to update otherwise we return false
. For e.g. I will add a new function to our render
example.
example of shouldComponentUpdate
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
}
}
handleButtonClick = (event) => {
this.setState({
counter: this.state.counter + 1,
});
}
// ------new function----
shouldComponentUpdate(nextProps, nextState) {
if (nextState.counter % 2 !== 0) {
console.log("Not updated");
return false;
} else {
return true;
}
}
render() {
return (
<>
<h1>{`Counter: ${this.state.counter}`}</h1>
<button onClick={this.handleButtonClick}>Click me</button>
</>
);
}
}
We just add shouldComponentUpdate
function and now our functionality of the counter will change as it will now display only "even" values. This happens because we are stopping the re-render from happening if the counter
is odd. Internally state
is indeed getting updated and if we click on the button again we will see the value of 2, 4, 6, and so on. We will not see any "odd" numbers even though setState
method is run, hence render is not called again to show the updated state.
Hope you now understand what is lifecycle in react and their methods. If you find any mistakes here kindly let me know in the comments
Top comments (0)