React Recipes

The Component lifecycle

This article reflects the React 16.4 API

There are two ways of defining components: as functions or as classes.

React constantly adds and removes elements from the DOM to reflect the state of your application. Each individual element in your app's element tree goes through three phases throughout its lifetime:

Components defined as functions are not aware of these phases. Whenever React needs to add or update a function-based element to the DOM, it evaluates the function. Props go in, UI comes out. When it needs to remove the element from the DOM, it just deletes its DOM subtree.

Class-based elements, on the other hand, afford more control. Besides being able to hold an internal state, you can define a handful of so-called lifecycle methods with which to observe and direct the component's behavior in each of these three phases.

Below we discuss each of the phases and the lifecycle methods relevant to them. For a more concise visual representation, see this interactive diagram.

The Mounting phase

When React reckons it needs to place an element in the DOM that was not there before, and notices the element is a class-based component, it will first create an instance of that class by calling its constructor.

A component constructor is optional: we only write it when we need it. This is the case for a couple of situations:

The following example does both:

class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 1
};
this.handleClick = this.handleClick.bind(this);
}

handleClick(e) {
this.setState(current_state => {
return {
count: current_state.count + 1
};
});
}

render() {
return <div onClick={this.handleClick}>{this.state.count}</div>;
}
}

The constructor receives the props as its only argument. The first thing you need to do in the constructor is to call super(props). (If you're curious why that's the case, Dan Abramov explains it here).

After calling the constructor, React does an initial render that consists of the following methods:

Finally, React lets us know the element's DOM is ready by calling componentDidMount.

As a recap, here's the succession of methods called in the mounting phase:

The Unmounting phase

The opposite of mounting is unmounting, when React no longer needs an element to be in the DOM. A single method is called before the component is removed from the DOM:

This is symmetrical to componentDidMount, so whatever you do in componentDidMount, you probably want to do the opposite in componentWillUnmount.

The Updating phase

Once a component is mounted to the DOM, all subsequent re-renders will follow the same sequence of lifecycle methods:

The succession is similar to the mounting phase, but with more hooks to control how the component responds to subsequent re-renders:

When does React re-evaluate, and possibly re-render a component? Whenever the state in your component instance, or somewhere above it in the element tree, was updated through a setState() call.

In particular, when you call setState() inside your component, React needs to re-evaluate it and see whether the updated state warrants updates to the DOM.

Similarly, when a parent component has its state updated, and its render() method invoked, its descendants are also re-evaluated with the props received from their parent.

Note: I'm purposely avoiding the word changed when talking about state updates. React does not check whether something in prop or state has actually changed or not when re-evaluating elements. It simply says: "here's what I have right now".

Error handling