In this lesson we'll use the matchPath
function exported by react-router to find active nested routes inside of a parent component. This technique can be used for comparing routes outside of a React component, or even inside of life cycle methods to do data loading.
Instructor: [00:00] There may come a time where the parent component is loading data for its nested child. However, you need access to a particular parameter on the URL. In our case, we have a profile path, but if you look here with a profile/1, that will still match our app.
[00:21] However, when we go and look in our profile at profile/1 and look at our params, we can see that the profileID is empty. The reason is because it is only matching the path here and it's not looking, and we're not indicating, to look for a profileID here.
[00:42] To make this work and to match the profileID so we can load data, we're going to first import matchPath from react-router-dom. The piece of the match that we care about is the parameters. We're going to create a function called const getParams, and it's going to receive a pathname. That pathname is going to be the active current path.
[01:06] We're then going to say const matchProfile is equal to matchPath, and the matchPath function takes a pathname, for example, profile/1, and then a series of props in an object. These props that we're passing in -- this object -- is the exact same props that we have here.
[01:32] In our case, we want to match the profile/profileID. Say path profile/profileID. This will match the pathname against this path, and it will then return the this.props.match that you would usually get as a prop in a React component.
[01:57] Here, we can then return matchProfile and matchProfile.params. We'll wrap this here. It'll return the params if the match profile exists, or it will just return an empty object.
[02:13] The reason we need to do this is because matchProfile.params may not exist if we are matching /profile, because this won't actually match the path of /profile, or it'll only match the path if it has a ID here. This will actually be undefined.
[02:35] Now that we have a function that will return the parameters, we're going to use componentDidUpdate. The reason we have to use componentDidUpdate is because this component will still be rendered when the profile route changes from either 1 or 2 or back to /profile.
[02:52] Now with componentDidUpdate, we get access to the current and previous location. We're going to destructure pathname from this.props.location, as well as get our pathname, but call it previous pathname from previous props.location.
[03:22] Now that we have our two pathnames, we can pass them into our get params to get the parameters for that particular path. Say const current params equals getParams for our pathname. Then we'll get the previous params to pass in our params for the previous pathname.
[03:49] Here, we can then compare the profileID if it exists, and then also if it has changed. We're going to say if the current params.profileID exists -- because it might not if we're at the /profile route -- then, we'll say current params.profileID doesn't equal the previous params.profileID. Then, we can load our data.
[04:18] In our case, we just have a loading flag. We're going to say this.setState loading true. However, we also need to then cause a fake delay. We'll do a setTimeout, and say this.setState loading false. We'll add a delay to our setTimeout of 500.
[04:41] To make sure that everything is kosher, we're going to say this.timeout equals setTimeout. We'll do a clearTimeout this.timeout, and then in our component, we'll unmount. We'll say clearTimeout this.timeout.
[04:59] That way, if this component is ever unmounted within our application, our timeout is cleared. However, this is just an example. This clearing of timeouts is a bit trivial, but will clean up any potential memory leaks.
[05:13] Now, we have our comparison of previous profile IDs. When we come back here and go home, we'll see that we have a select profile screen, and we'll click on profile1. It'll say loading, and then switch back, profile2, and then switch back.
[05:31] We can see that here, because we're passing in our loading flag. This way, our parent component, which doesn't generally get access to the profileID, is matching against the profileID, comparing if it's changed, and then triggering a data load which we can then pass down to our nested component.