When creating a React class component, you define its props and state, how it’ll handle user generated events, and how it’ll render, but you don’t directly control when those things occur. And while you can add your component to another component’s render
method (making it a child of that component), you don’t control when your component will be loaded into (or unloaded from) the component tree. You also don’t control when your component will be updated and re-rendered.
The lifecycle of a component is simply a way of describing the key moments in the lifetime of a component: when it’s loading (i.e. mounting), updating, and unloading (i.e. unmounting).
When you finish this article, you should be able to:
componentDidMount
, componentDidUpdate
, and componentWillUnmount
; andcomponentDidMount
component lifecycle method to fetch data from an API.Each class component has several lifecycle methods that you can add to run code at specific points in a component’s lifetime:
componentDidMount
- This method is called after your component has been added to the component tree.componentDidUpdate
- This method is called after your component has been updated.componentWillUnmount
- This method is called just before your component is removed from the component tree.Let’s take a closer look the process that occurs when a component is mounting, updating, and unmounting.
When a class component is being added to the component tree, the following process occurs:
constructor
method is called;render
method is called;componentDidMount
lifecycle method is called.A component will update if it receives new props or if the setState
method is called.
When a component receives new props, the following process occurs:
render
method is called;componentDidUpdate
lifecycle method is called.When a the setState
method is called, the following process occurs:
render
method is called;componentDidUpdate
lifecycle method is called.Just before a class component is removed from the component tree, the componentWillUnmount
lifecycle method is called.
To see a visual depiction of the above processes, check out this interactive lifecycle diagram.
In earlier versions of React, there were additional lifecycle methods that you could use. These methods are now deprecated and are marked as “unsafe” to use (because they’ll eventually be removed from React’s API).
The legacy lifecycle methods are:
Sometimes you’ll encounter these lifecycle methods in older articles and code examples when researching React online. To learn more about these lifecycle methods, see the official React documentation.
To see the componentDidMount
, componentDidUpdate
, and componentWillUnmount
lifecycle methods in action, you can create a couple of simple React class components.
For the first class component, you’ll define the componentDidMount
, componentDidUpdate
, and componentWillUnmount
lifecycle methods and render an <h2>
element using the this.props.text
prop for its content:
// ./src/LifecycleMethods.js
import React from 'react';
class LifecycleMethods extends React.Component {
componentDidMount() {
debugger;
}
componentDidUpdate() {
debugger;
}
componentWillUnmount() {
debugger;
}
render() {
return (
<h2>{this.props.text}</h2>
);
}
}
export default LifecycleMethods;
The debugger
statements will cause the browser to break within each of the lifecycle methods when they’re invoked.
For the second class component, you’ll create a component that’ll use the LifecycleMethods
component:
// ./src/Demo.js
import React from 'react';
import LifecycleMethods from './LifecycleMethods';
class Demo extends React.Component {
constructor() {
super();
this.state = {
displayComponent: false,
componentText: new Date().toLocaleString(),
};
}
loadComponent = () => {
this.setState({ displayComponent: true });
}
unloadComponent = () => {
this.setState({ displayComponent: false });
}
updateComponent = () => {
this.setState({
componentText: new Date().toLocaleString(),
});
}
render() {
return this.state.displayComponent ?
(
<div>
<div>
<button type='button' onClick={this.unloadComponent}>Unload Component</button>
<button type='button' onClick={this.updateComponent}>Update Component</button>
</div>
<LifecycleMethods text={this.state.componentText} />
</div>
) : (
<div>
<button type='button' onClick={this.loadComponent}>Load Component</button>
</div>
);
}
}
export default Demo;
Notice that the component renders buttons to control when the LifecycleMethods
component is loaded, updated, and unloaded. Having these buttons will allow you to interactive trigger each of the lifecycle methods defined within the LifecycleMethods
component.
If you’re following along, be sure to update your React application’s entry point to render the Demo
component:
// ./src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Demo from './Demo';
ReactDOM.render(
<React.StrictMode>
<Demo />
</React.StrictMode>,
document.getElementById('root')
);
Then run your application (npm start
) and open the developer tools console in your browser. Here’s the application just after clicking the “Load Component” button. Notice that execution is paused within the LifecycleMethods
component’s componentDidMount
lifecycle method!
A common use case for the componentDidMount
lifecycle method, is to fetch data from an API after a component has been mounted to the DOM. Here’s an example of a class component that uses the componentDidMount
lifecycle method to retrieve the public repositories for the provided GitHub username and render the repositories as an unordered list of links:
// ./src/FetchingData.js
import React from 'react';
class FetchingData extends React.Component {
constructor() {
super();
this.state = {
repositories: [],
};
}
componentDidMount() {
const url = `https://api.github.com/users/${this.props.gitHubUsername}/repos`;
fetch(url)
.then((response) => response.json())
.then((data) => this.setState({ repositories: data }));
}
render() {
const { repositories } = this.state;
if (repositories.length === 0) {
return (
<div>Fetching data...</div>
);
} else {
return (
<div>
<h2>GitHub Repositories for {this.props.gitHubUsername}</h2>
<ul>
{
repositories.map((repo) => (
<li key={repo.id}>
<a href={repo.html_url}>{repo.name}</a>
</li>
))
}
</ul>
</div>
);
}
}
}
export default FetchingData;
In the above example, the FetchingData
component initially renders <div>Fetching data...</div>
. Once the component is mounted to the DOM, the componentDidMount
lifecycle method is called, which in turn uses the Fetch API to retrieve the public repositories for the provided GitHub username. When the fetch HTTP request completes and the JSON response is parsed, the this.setState
method is called to update the this.state.repositories
property with the newly acquired data. Updating the state causes React to re-render the component which then displays an unordered list of links.
If you’re following along, be sure to update your React application’s entry point to render the FetchingData
component and to set the gitHubUsername
prop on the component to a valid GitHub username:
import React from 'react';
import ReactDOM from 'react-dom';
import FetchingData from './FetchingData';
ReactDOM.render(
<React.StrictMode>
<FetchingData gitHubUsername='appacademy' />
</React.StrictMode>,
document.getElementById('root')
);
Here’s the component displaying the public repositories for the appacademy
GitHub username:
In this article, you learned how to:
componentDidMount
, componentDidUpdate
, and componentWillUnmount
; andcomponentDidMount
component lifecycle method to fetch data from an API.In addition to the componentDidMount
, componentDidUpdate
, and componentWillUnmount
lifecycle methods, there are additional rarely used lifecycle methods. To learn more about these additional lifecycle methods, see the official React documentation.