React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.
To build single-page apps, we have to have some way to map URLs to the React component to display.
In this article, we’ll look at how to create 404 routes and recursive paths with React Router.
404 Routes
We can create 404 routes to show something when none of the routes we added are matched.
To do this, we can use the asterisk as a wildcard character.
For example, we can write the following code;
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
function Foo() {
return <h3>Foo</h3>;
}
function Bar() {
return <h3>Bar</h3>;
}
function NotFound() {
return <h3>Not Found</h3>;
}
function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Foo</Link>
</li>
<li>
<Link to="/bar">Bar</Link>
</li>
<li>
<Link to="/doesnt-exist">Doesn't Exist</Link>
</li>
</ul> <Switch>
<Route exact path="/">
<Foo />
</Route>
<Route path="/bar">
<Bar />
</Route>
<Route path="*">
<NotFound />
</Route>
</Switch>
</div>
</Router>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
In the code above, we have the Switch
component that has the following Route
:
<Route path="\*">
<NotFound />
</Route>
It’ll match any URL that doesn’t match the other routes.
Therefore, when we click the Doesn’t Exist link, we’ll see Not Found.
This also applies when we type in anything other /
or /bar
as the relative path.
The *
is the wildcard character for matching anything.
Recursive Routes
Just like any other routes, we can define routes recursively. The only difference is that we reference the component within the Route
with itself.
For example, if we have an array of NEIGHBORS
as follows:
const NEIGHBORS = [
{ id: 0, name: "Jane", neighbors: [1, 2, 3] },
{ id: 1, name: "Joe", neighbors: [0, 3] },
{ id: 2, name: "Mary", neighbors: [0, 1, 3] },
{ id: 3, name: "David", neighbors: [1, 2] }
];
where the neighbors
array references the id
of the other entries.
Then we can define a Neighbor
component and use it as follows:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import { useParams, useRouteMatch, Redirect } from "react-router";
const NEIGHBORS = [
{ id: 0, name: "Jane", neighbors: [1, 2, 3] },
{ id: 1, name: "Joe", neighbors: [0, 3] },
{ id: 2, name: "Mary", neighbors: [0, 1, 3] },
{ id: 3, name: "David", neighbors: [1, 2] }
];
const find = id => {
return NEIGHBORS.find(p => p.id === id);
};
function Neighbor() {
const { url } = useRouteMatch();
const { id } = useParams();
const neighbor = find(+id); return (
<div>
<h3>{neighbor.name}’s neighbors</h3> <ul>
{neighbor.neighbors.map(id => (
<li key={id}>
<Link to={`${url}/${id}`}>{find(id).name}</Link>
</li>
))}
</ul>
<Switch>
<Route path={`${url}/:id`}>
<Neighbor />
</Route>
</Switch>
</div>
);
}
function App() {
return (
<Router>
<Switch>
<Route path="/:id">
<Neighbor />
</Route>
<Route path="/">
<Redirect to="/0" />
</Route>
</Switch>
</Router>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
In the code above, we have the find
function to make find neighbors easy.
Then in the Neighbor
component, we have:
const { id } = useParams();
const neighbor = find(+id);
to get the id
from the URL, and then find the neighbor
with it using the find
function.
Then we display the neighbors of the neighbor by writing:
<ul>
{neighbor.neighbors.map(id => (
<li key={id}>
<Link to={`${url}/${id}`}>{find(id).name}</Link>
</li>
))}
</ul>
Then we have a Switch
component that has Neighbor
again in the Route
:
<Switch>
<Route path={`${url}/:id`}>
<Neighbor />
</Route>
</Switch>
This is the part that’s recursive, since Neighbor
references itself here. We set the path
to `${url}/:id`
so that when the Link
s above is clicked, we’ll see the new neighbors.
Then in App
, we just have the usual routes. Once again, we have path=”/:id”
to find a neighbor by id
.
Conclusion
We can define 404 routes easily by setting the path
‘ value of the Route
to an asterisk.
To define recursive routes, we can reference routes within itself. It’s treated no differently than any other kind of route.