componentDidUpdate in React. Let’s dive in!
Let’s take a scenario where we’re building a blog app. The blog will be very minimal, with these features:
- 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.
- 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.
- 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
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
This is how our sample post data looks like:
The final piece of the puzzle is the
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 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.
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.
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
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):
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!
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!