The React Component Lifecycle

Something I was asked recently was to name all stages of the React class component lifecycle. After a short pause I was able to name a few but later came to realize there were more I wasn’t aware of. Unsatisfied with this I decided to take a closer look into this subject and after doing so I feel like I have a much deeper understanding of how this part of React works.

I welcome you to join me as I dive down the rabbit hole and attempt to explain what each one does, and how they can be used. In this piece I’m going to focus on React 15.

render

Let’s start with the basics, render(). The render method is required on every React class component and returns a React element. What the element consists of is up to you, but typically you’d return some JSX which makes use of either this.props or this.state. If you don’t want to actually render anything you can simply return false or null.

See the Pen React Component Lifecycle: render by James Ives (@jamesives) on CodePen.

The React documentation states that the render method should be pure, meaning it shouldn’t modify the components state, this functionality should be off-loaded to another function or lifecycle method. For instance calling this.setState({ species: 'cat' }) inside the render method is something you shouldn’t do.

constructor

The constructor(props) method is called before the component mounts and allows you to initialize a components state and do any neccersary class setup such as binding class methods, calling a super class, and more. If you decide you don’t need component level state or that you don’t have a need for a constuctor you can simply omit it, it’s optional.

The constructor method should be called with super(props) otherwise props will wind up being undefined inside the constructor.

See the Pen React Component Lifecycle: constructor by James Ives (@jamesives) on CodePen.

There are a number of considerations that should be made when using the contructor that can be found in the React documentation.

componentWillMount

This part of the lifecycle is useful for making adjustments to our components before the render() method is called. At this stage both this.state and this.props are defined and can be accesed, so this is a great place to make any adjustments and preperations before rendering.

In the example below we pass in an animal name via props and then use componentWillMount() to figure out what species that animal is. We then apply the species to our state and use that state in the render() method to show the name of the animal, and its species.

See the Pen React Component Lifecycle: componentWillMount by James Ives (@jamesives) on CodePen.

componentDidMount

The opposite of componentWillMount(), this method is called immediatly after a component has finished mounting. When this method is called you can safely assume that the components children have also mounted and ran their own instance of componentDidMount(). In the example below the ‘Queen’ component mounts before the ‘King’, allowing us to make use of this.refs.queen to focus the input element.

See the Pen React Component Lifecycle: componentDidMount by James Ives (@jamesives) on CodePen.

componentDidMount() is also a great place to start initiatlizing a remote request. In the following example I started a promise once the component mounts, and once it resolves I toggle the ‘loading’ state to false, and then bind the response to my ‘posts’ state. This causes the component to re-render with all of our remote content.

While components can be re-rendered repeatedly, componentWillMount() and componentDidMount() are only called once.

See the Pen React Component Lifecycle: componentDidMount Fetch by James Ives (@jamesives) on CodePen.

componentWillRecieveProps

The first stage of the update lifecycle is componentWillRecieveProps(nextProps), this method is triggered only when a components props value is altered, just calling this.setState without altering props will cause this method to be skipped. This allows us to make comparisons between the current and new value of props, giving us the ability to prepare for the incoming change.

In the example below we use the componentDidMount() method to change the name state of the ‘Parent’ component which is then passed into the ‘Child’ component as props. This causes componentWillRecieveProps() on the ‘Child’ component to fire. I check to see if the value of this.props.name is not the same as nextProps.name and if it’s I fire an internal method to play an animation.

See the Pen React Component Lifecycle: componentWillRecieveProps by James Ives (@jamesives) on CodePen.

With most of the lifecycle methods there are a few things to consider, such as this.

shouldComponentUpdate

The next step is shouldComponentUpdate(nextProps, nextState) which allows you to decide if the component should actually update or not. This lifecycle method allows you to cancel the update process and can be useful for providing optimization to your application.

The example for this method passes the name ‘McGregor’ to the ‘Champion’ component as props when the button is pressed. We then hook into shouldComponentUpdate() and return false if nextProps.name equals ‘McGregor’. Because this method by default returns true it’s not neccersary to specify anything or include it in many cases.

See the Pen React Component Lifecycle: shouldComponentUpdate by James Ives (@jamesives) on CodePen.

componentWillUpdate

The componentWillUpdate(nextProps, nextState) method is similar to componentWllMount() with the primary difference being that it’s run every time the component has determined that it needs to re-render, such as whenever its state or props have changed. In this method we have access to nextProps and nextState, allowing us to make comparrisons between the two before re-rendering occurs.

In the example we make comparrisons between this.state and nextState and use the occurance of a change to trigger a method that plays an animation right before the component re-renders with the updated state. This will be near impossible to see, but you can run some console logs between componentDidUpdate() and componentWillUpdate() and see which fires first.

See the Pen React Component Lifecycle: componentWillUpdate by James Ives (@jamesives) on CodePen.

It’s important to note that in you’re unable to call this.setState() during this phase of the update cycle.

componentDidUpdate

You guessed it, componentDidUpdate(prevProps, prevState) is equivalent to componentDidMount() and in this method you have access to the same sort of data. At this point our component has gone through the entire update lifecycle. Here we can access prevProps and prevState which give us the value of each before the component updated.

In the following example I use this.refs wrapped in jQuery to animate the box when the button is clicked and the component has finished updating.

See the Pen React Component Lifecycle: componentDidUpdate by James Ives (@jamesives) on CodePen.

componentWillUnmount

The final stage in a components lifecycle, componentWillUnmount(). This is called whenever the component unmounts, for example when the user changes pages. In this method we clean up any setup we did such as removing any event listeners, or cancelling any in-flight remote request calls.

In this final example we pass a cancellation token into Axios when the component unmounts. This will cause the in-flight request to be cancelled if the component unmounts while it’s processing.

See the Pen React Component Lifecycle: componentWillUnmount Fetch by James Ives (@jamesives) on CodePen.

In Review

In review our component goes through three cycles. The first occurs when it’s introduced.

  • constructor(props)
  • componentWillMount()
  • render()
  • componentDidMount()

Whenever we update state or props our component goes through an update cycle.

  • componentWillRecieveProps(nextProps)
  • shouldComponentUpdate(nextProps, nextState)
  • componentWillUpdate(nextProps, nextState)
  • render()
  • componentDidUpdate(prevProps, prevState)

And then we have the last cycle which occurs when the component is de-comissioned.

  • componentWillUnmount()

Wrapping Up

Armed with this information you should now have a deeper understanding of what happens in every stage of a React class components life. You can sort of compare this to how Neo see’s the Matrix, except with JavaScript.

If you have any questions please feel free to reach out on Twitter or via my contact form.