Implementing a Catch All Route with React Router
Now that we have the basic routing that we're going to need in our application, both the hard-coded routes and the dynamic routes for our portfolio items, what I'd like to talk about now is what happens when the correct route is not entered.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So if you are using a MVC framework, and if you've never heard of MVC before, what that stands for is model view controller. It is the way that you build an application if you use, say, the Ruby on Rails framework, or Django, or Java Spring, or one of those types of frameworks. And when you go to a route that doesn't exist there, the typical approach, with that framework, is they will give you an error, because they are serving up documents, they are not a single-page application.

Now, with our application, though, we only have, once again, that one page, and so because of that, every one of our routes, whether it exists in our route definition or not, is going to simply show the page, and sometimes that can be confusing. So take, for example, if you were rebuilding Twitter, or some-type application like that, and if you went to a URL that didn't exist, and we can test out right here, see what the natural behavior would be.

So if I went to Twitter, and then typed in a bunch of gibberish for the username, you don't get an error page. It simply says, "Sorry, that page doesn't exist!" So it didn't bring up a server error page.

large

Now let's see what happens if we do that in our application. So I'm going to go into here, type a bunch of gibberish in, and you can see, where did it take us? Well, it took us nowhere, because there was no match.

large

And so it still shows the navigation bar, but it doesn't really give us a lot of details, and it definitely wouldn't give our users details and information, letting them know they went to the wrong route, and that can be a little bit confusing, so let's build a way to give them some feedback if they get on the wrong page.

Go the Visual Studio Code, and let's create a new component. I'm going to call this component NoMatch, and we will access this one from pages, and then we're just gonna call this one no-match. And the way that you define this type of route, this is going to be a catch-all route, another way of saying it is kinda similar to a 404 except one where you're actually giving some information. Is down here on the bottom, and the route per RAM, with React Router, is very flexible, even to the point where you can pass in an entire route without pointing to a route.

Now I know that may sound a little confusing, so what we're doing is we're defining a route that doesn't actually have a path and so what that's going to do is it's going to take advantage of the way a switch statement works. So remember that switch statements are like conditionals. We're checking to see, okay, was this at the homepage? No, okay, we'll move on. Was it the about-me, is that the route? No, okay, was it contact? No. It'll keep on going down 'til it finds a match.

Now, when you pass in a route that does not have a path, then that will be the route that gets picked up. And so one thing to be very careful about, with this, you would never put this route at the very top of your switch statement, because then it would be the route that would always get captured and so you definitely don't want this.

So this is kind of like in a conditional, this is like the very last item on the conditional, this is like the else. So in other words, if no matches are found anywhere, this is what we want to provide. So I'm going to say that this component is going to be NoMatch, and now we have to go and create that component. So I'm gonna go into pages, let's close out portfolio. New File, and this is just gonna be no-match.js and this is gonna be a plain, functional component. So I will use my user snippet and we can say something here, let's put it in an h2 tag, and just say something like, "We couldn't find that page" and then let's also give a link after this.

So we're gonna say an h2 and then right below it, we'll import a link, and let's point them to the homepage. I think that's kind of a natural way of doing it, and so we'll say Link to, and pass in just the slash, and for our link text, we could say something like, "Return to homepage," close off this link, and then make sure you import it up top. So I'm gonna say I'm wanting to import Link from react-router-dom and now this should work. We don't need to bring in props or anything like that.

no-match.js

import React from "react";
import { Link } from "react-router-dom";

export default function() {
    return (
        <div>
            <h2>We couldn't find that page</h2>
            <Link to="/">Return to homepage</Link>
        </div>
    );
}

So let's test this out in the browser. Oh, I don't even need to refresh, it pulled it right up. So now this says, "We couldn't find that page," and then, "Return to homepage."

large

And you can see all of our other routes are still working. So this is exactly the behavior we want, but if we come up top, and we, once again, give some gibberish, then it's gonna say, "We couldn't find that page", so this is working perfectly.

Now one caveat, 'cause I have had this happen in previous courses, where someone had built out this kind of feature, this catch-all route, and then they thought it was weird, because they would go to a slug-based route, like this portfolio one. And they would come here, and instead of Quip, or one of the four that we gave, they would put some gibberish there, hit return, and they'd say, "Our catch-all didn't work."

And the reason for that is because this type of route, here, is technically going to be found in our route definition, right here, on line 28. So even if there may not be a slug that exists, it's not going to keep going down, that component's job, then, would be either to redirect, or to give some information, so I did wanna provide that.

Now, what would happen, on the other hand, if I said portfolio slash, put some gibberish there, something that didn't exist, another slash, and then hit return and you can see it's still showing up. So you might think that this is confusing because here, we are giving multiple slashes. And one thing I will say, in an MVC framework like Ruby on Rails, or like some of those, this would trigger an error, because their routing system would match, and if it sees another slash, it would not capture that as a route, but in React, that still will be caught here.

Now if you do not want that, then what you would need to do is give exact, and then hit save, come back and now it says, "We couldn't find that page." So that is another example on when you'd wanna use exact, because if you need to make sure that the pattern that you're providing with the path is matching exactly what you're wanting, which is what we're seeing right here, so this is a great example of another spot to use exact, then you would wanna use a tool like this.

And eventually, later on in the course, we're going to be using exact for blog details, and in a few other places. So hopefully, by the end of the course, you'll get a good feeling for when you'd want to use that exact rule, and when you wouldn't. But great job if you just went through all of that section and you have the application working, you now have all of the key basics you're going to need in order to implement routing in your React app.

Resource