Working with React and JavaScript is always fun because it’s always a chance to learn something new. Today we’ll visit one such case I came across recently that helped me learn more about when to use componentDidUpdate in React. Let’s dive in!

Scenario

Let’s take a scenario where we’re building a blog app. The blog will be very minimal, with these features:

  1. When a user visits the homepage, they should see a list of posts and should be able to click on any of the posts to be taken to the blog post’s page.
  2. When a user visits a blog post page, they should see the blog details i.e. title and content, and a list of recommended posts at the bottom of the page.
  3. Clicking on a recommended blog post’s link should take the user to that post’s page.

Now that we’ve figured out the requirements, let’s proceed to build the app.

Building the App

We will need 3 components for our app: the home page, the blog post component and the app’s root component, which decides which page to render depending on the route. For this example, we’ll fetch the posts from a local file rather than making network requests.

Let’s start off with the root component, which is where we’ll mount the app to a specific DOM node.

We’re using the ​​react-router-dom package to render either the Home or PostDetails component depending on the route. A request with a URL such as /posts/2 will be routed to the PostDetails component and the postId variable will take the value of 2.

Let’s look at the Home component, which will act as our homepage:

In this file, we fetch posts locally from posts.js and use  the Home component render a list of links to each of the posts. Each post has an id attribute which is used to construct the URL using the Link helper from react-router-dom​

This is how our sample ​post data looks like:

The final piece of the puzzle is the ​​PostDetails.jsx component:

In this component, we’ll store the post’s details in the component state, and all the values are initially empty. To fetch the post’s data, we’ll need to extract the postId parameter from the URL. ​​​​​​​​​​​​​​react-router-dom stores the route params in the component’s props and it enables us to access this parameter via this.props.match.params.postId. Once we have the postId, we then find the post with a matching ID in the posts array, and set it in the component state. This is handled in thefetchPostData function.

In the ​​render method, we show the post’s details and a Recommeded Posts section. When you click on one of the posts in this section, you should be taken to that post’s URL and shown that post’s details.

You can try out the app in it’s current state at CodeSandbox and also view the live code in the Live Editor

However, we have a bug lurking somewhere in our code. Try clicking on one of the recommended posts and see what happens.

Figuring out the Problem

If you haven’t tried out the live app, the issue we have is that when we’re in a blog post’s page, clicking on a recommended post doesn’t seem to do anything. If you’re keen though, you’ll notice that the URL does change but the page content doesn’t change 🤔

When you click on a recommended blog post link, React Router re-renders the PostDetails route component with a new postIdparameter. This parameter is passed to the component as props. We can be sure the component does receive new props since the URL changes. But why does the component fail to display the updated data?

The root of the issue here is that we fetch data only on componentDidMount which is not called when a component re-renders.

What we need to do to solve the problem is to fetch new post data when we detect that the postId parameter has changed. This is where componentDidUpdate comes in.

Solution

Here’s a comment I came across in the react-router issue tracker that let me down the right path.

You probably want to just respond to prop changes with componentDidUpdate to refetch data when the same route is active but with different parameters

Ryan Florence

Therefore, to fix the issue, we have to add componentDidUpdate, where we’ll check if the postId has been updated and then fetch the details of the new post. Once we have the new details and store them in the component state, the component re-renders and shows the updated content.

Here’s the small addition we need to make to fix the bug (L18-28):

The componentDidUpdate lifecycle method takes in the previous props as the first argument. We extract the postId from the previous props, and compare that with the postId from the current props. If there’s a change, we fetch new data using the current postId parameter. This helps us update the page content when the component re-renders with a new postId parameter, and this fixes our bug!

You can try out the new bug-free version on CodeSandbox and check out the code on the Live Editor. If you’re interested in the accompanying code samples, you can access them on GitHub.

And thus ends the story of how I learned how to use componentDidUpdate on a real practical problem. This was an interesting discovery for me and I hope you’ve learnt something new too!

Featured Photo  (CC BY 2.0) courtesy of Malin Bobeck 

One thought on “A Practical Use Case for React’s componentDidUpdate

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.