Here is an application that is currently using the preact-router. We have a home component that is loaded when we hit the home page. We have a profile page that receives a user prop. We have an error page should we visit a path that is not listed in any of these components.
Now, if we wanted to continue using Preact for its speed and small file size, but we wanted to use the react-router, which is the most popular router from the React community, then we can do that. We just need to change a couple of things in our application.
The first thing we need to do is install preact-compat. We're over on the command line. We can type, young@preact-compat. Whilst we're here we'll also install react-router-dom. Now we need to add an alias in our webpack configuration. We'll add resolveAlias and then we'll alias both react and react-dom to preact-compat.
Inside the react-router library it's going to expect to be able to bring in react, so by providing these here, when they attempt to do that, webpack will switch out react with preact-compat, which has all the little bits in there to make other libraries think that preact-compat is actually react, such as prop types and things like that.
We add this alias, solely for the purpose of the react-router library. Now let's go back to our app and start using react-router. The first thing we'll do is change this import. Instead of using preact-router, change that for react-router-dom.
We'll want the browser router. We'll also need a few more components from this library. We'll need route and switch. Now we can redefine our paths and components in a way that react-router understands. Let's white these out and start again.
We'll wrap these in a switch component, as we only ever want to render one of them at a time. Now, for each path we have, we will use a route component. For the home page, we want to match the exact path of / and when this matches we'll load the component home.
We'll follow the same pattern for profiles, except we don't want exact. We'll provide profile, call end user, so that we can get the username from the URL. We'll provide the profile component.
Finally, for the error page or the 404 page, we can provide it here and then just remove the path altogether. The switch will handle this for us. If none of these two match, this component will load. When we reload the page, we can see that everything appears to be working. But we're not quite there yet. Let's try it out and see what happens.
Type Shaky Shane, Enter, and we get nothing. Let's open up the home component, see what's happening. The Preact router gives us this route function that allows us to navigate from anywhere in our application. We don't have that with react-router. What we do have is a higher-order component that we can use to wrap this home component and it will give it access to the router.
We'll change this for react-router-dom and we'll get hold of withRouter. Now let's wrap this home component. We'll change this to instead say constHome is equal to the result of calling this higher-order component with our component. This is a function, so the arrow here. This will give us access to the router here. That means we can pass it into the search function as the first parameter.
Then we can change the signature here to accept the router. We'll change this to instead be router.history.push. Here, we are interacting with the react-router directly. Finally, if we export this as a default, and see what happens when we hit Save.
Again, we'll type in Shaky Shane, hit Enter, and you can see we don't get the result we expect. Which is fine, because at least we navigated to the right place and we know we're almost there. Now let's go into the profile component and figure out why we're not getting what we expect here.
The reason we're getting David here and not Shaky Shane is that the way in which react-router gives you access to the properties or to the matches in the path is different to how it works in preact-router. But this is an easy fix. Let's just say constUsername=this.props and react-router gives us a match. From that we can say on the params give me the user.
You can see that this maps on to what we provided here. Now we can substitute this for username. Save. When it reloads there, you can see it's correctly accessing this segment of the URL, pull in GitHub's API, and load in the profile component as we expected. To finish this lesson, let's check that the error or the 404 page is working correctly.
If we hit a URL here that doesn't match any paths that we've defined, you can see we do get the error component. But if we click home now, you can see that that actually reloaded the page. It didn't navigate internally within the app. Now let's go into the error component and see why that is.
The preact-router hijacks any links on the page like this and makes it seamlessly work with the router. But with react-router, we need to bring in another component called link. We'll replace this anchor here with a link and we say two, and that should be enough.
Behind the scenes, react-router will replace this with a regular anchor link. You hit Save, try and access a page that doesn't exist again, we get the error, and if we click Home, you can see we were navigated immediately back to the home page.
To recap, you can absolutely use Preact with react-router. You just need to add those few lines in your webpack configuration and then you can use the router exactly as you would with React.