How to Customize React Router Hooks

We'll discuss the small changes that can be made to use some of the new Hooks that React Router provides.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two

We won't be writing any code in this lesson, but instead, just address a few small changes that can be done to comply with a newer update for the React Router library. React Router is the library we use in our React application for part two of the course to essentially create routes to different pages in our app. And essentially what this does is based on the route that the user is in, a different component is shown. So we have the home component being shown in the index routes or the home page. If I go to a certain listing or listings, so in this particular case we're looking at the listings/toronorout, I see the listings component we've created. If I go to a listing, I'll see the listing route be shown for a certain ID and the listing component be shown. And React Router is the main library here that helps control which of these high level components get shown based on the route that the user is in. With the emergence of React Hooks, React Router has made an update to their library to now bring in a more hook based API. The blog post here that was created by the team behind React Router essentially talks about the future of React Router and the reach router library. Now the reach router library is another library created by the same team to achieve the same outcome. And essentially this blog post, it's too long in a read essentially states that they're bringing the best of both React Router and reach router into a new hook based API and React Router is the surviving project which is the project that we're using in our tiny house application. And the change that's been made is in a minor release which basically means that it's 100% backwards compatible. So everything we've done in the course when you go through module 1 to module 13, practically everything we've done is compatible with the latest version of React Router. However, there are some small changes that can be made to use a more hook based API. And that's where we're going to talk about in this lesson. With that said, we're going to go to the code now and we're essentially going to show you the small changes that can be made to update from where we were at the very end of the course to using the hook based API of React Router. And we'll start at the root level source index file where we have the parent app component that essentially determines which child component is going to be rendered based on which route. And we've achieved this by using the switch statement from React Router and then using the route components to determine which of these components should be shown for which path. If we recall, what we've done before is we either used a component prop to determine which component should be shown, which can still be used, or we used the render function that React Router gives us for the route components. And this render function essentially allows us to render a component with a function that gives us the ability to pass additional props from the route component down to each individual child component. Now we don't need this any longer. Why? Because in each of these child components, we can use hooks to get certain information on a route level. So with that being said, our switch statement now appears a lot simpler. All we do is have our route components be the parent of the child components you want shown for each path. So for the index path, we want to see the home component. For the host path, we want to see the host component. For the listing path, we want to see the listing component. For the listings path, we want to see the listings components and so forth and so on. With that said, now let's look at a few of the components we have here and determine and see how we can use the hook based API to get the information we're looking for. Now we've seen before that in certain components that are being rendered with React Router, we can essentially access the URL parameter of the route thanks to what React Router provides. So as an example, in the user component, based on the ID the user visits, this essentially tells us what the user, the user, the viewer is looking for. So what we do is we essentially try to access the value of the ID parameter. We fire the query and pass in the appropriate ID information. And before to actually access this ID URL parameter, we attempted to access the match object prop that every route component would essentially pass down to every component purely for the fact if we used the render props pattern. However, in this case, we're not doing that any longer. To access the params in our route, all we essentially need to do is use the use params hook from React Router. This use params hook is a generic that takes essentially the shape of the parameters in our URL. So in this context, we're saying there's going to be an ID parameter of string type. We can then destruct the parameters from this hook and we have what we're looking for a lot more simpler and a lot more straightforward than trying to access a match object and using the route component props interface from React from React Router to help shape that. All we do now is just use the use params hook, retrieve the ID parameter or any parameter in our URL and we're good to go. Let's take a look at another component. Let's take a look at the stripe components. In this component and a few other components as well, we needed access to the history object that React Router provides because this allows us to essentially change the browser position or basically push or replace a new entry to the browser stack or in simpler terms, basically redirect the user or move the user around within our application. So before in this particular case for the stripe component, an example of this was if the user tries to access the stripe routes without a code in the URL parameter, we just take them directly to the login page because there's nothing else to see in this component. To access the history object before, we did the same as we've done for the other component. The user component is we basically use the render props pattern that the route component provides and basically propagated the props down to the child components. Now we don't need it and we don't need to do that any longer. What we do in this case is we just simply use a hook label to use history and this hook essentially gives us the history object we're looking for. That's all we need to do. We just simply retrieve this history object and use it the way we've used it before. And somewhere else we'll look at right now is the app header component. The app header component is unique because it's one component that we show regardless of what route the user is at. So the user is visiting the index route, the host route, whatever. We simply display the app header component above and the app header component does need access to a few route specific information. It essentially needs access to the history object as well as the location object. We're using the history object because the app header has the search inputs where the user can type information and when the valid information is provided, we just take them to the listings page with that information. And we use the location object because when the user visits the listings page directly, we want to determine what path name the user is visiting and we append it into the search input itself. We're using the location input here and not the match object prop we've seen before because the app header component is not route relative, right? So in this case, this app header component isn't being rendered within a route. So we don't have the context of what the URL parameters is. So we try to determine what the path name is manually, right? Before since the app header components was not route relative, we actually had to use the width router higher order function to essentially provide the history and location objects, not any longer. It's a lot more simpler, a lot more straightforward. All we need to do is use the hooks that we're looking for, use history, use location. With these hooks, we can get the history object and the location object. And with both of these objects, we can just use them the way we've used them before. Very straightforward. And that's pretty much it. In any of the other components that we other, whether we need the history objects or any of the route params, we just use one of these hooks. So before we summarize what we've just talked about, the one other thing that's worth mentioning is if you want to use the hook based API, you'll need to update your React Router DOM library to version 5.x. So we've updated here from 5.1. So both the React Router DOM library as well as the community developed types definition to 5.1 and above. And you can use the hook based API. And since it's backwards compatible, you can also use the traditional way of doing things which is totally fine as well. So to summarize, there's a few things we do within our app that's essentially route specific. So if we need to access the params of our routes, all we need to do is essentially just destruct the param we're looking for, use the use params hook. And we can also specify the interface here that can describe the shape of the param that we're looking for. If we need to access the history object, all we need to do is just get the history object directly from the use history hook. If we need to access the location object, which gives location specific information of the routes, all we need to do is just get the location object with the use location hook. So this is primarily the three route specific things we do in our app. And as long as you just use these hooks, we're good to go. We don't need to worry about the width router, higher order function in certain cases. We don't need to worry about the route component props interface to describe the shape of props, because in this case, these values aren't props any longer. They're just simply properties we get from the hook functions available to us. In the lesson documentation, we're going to summarize each of these different hooks and what they're useful for. So whether you're seeing this before you're beginning the course or in the middle of the course, you're welcome to use any of these hooks. If you see this at the very end, you can just restyle what you've done to use these hooks. Remember, the takeaway is the outcome is the same. We're just accessing the params of our route, the history object or the location object. The hooks just make it a lot easier and just give us a different way to access this information. [BLANK_AUDIO]