React Router Dom Essentials
Use routes in your react Single Page Application
Hey there! In this article, we’ll cover how to add routes to a React app.
It will be useful if you are familiar with these concepts:
- ES6 syntax
- JSX.
- React: functional components.
- The repository
- A little context first
- Starting a project
-
The initial routes.
- The HashRouter component
- The Route component
- The Switch component
- The Redirect component
- More juice using Link
The repository
Show, don’t tell, right? Here is the repository with a quick example for you to clone it.
git clone git@gitlab.com:sespinoz/react-router-dom-essentials-book-example.git
Quick note: At the moment of writing this article we are using react-router-dom
5.2.0
.
As a good React Developer, you should always have the official documentation opened and also try things for yourself :)
A little context first
When the web was younger, routing meant to ask for a new HTML page to the server each time a user clicked on a link inside a page. This meant more traffic, more delay in loading that page and a poor user experience.
With React, you’re able to create Single Page Applications (SPA), which means that you only have to request for the page once, and then you can manipulate the DOM to change the content of the current page on each event triggered by the user. This indeed can be achieved with vanilla javascript, but there are libraries like react-router-dom
that will help you to do just that.
React is a lightweight library, not a complete framework like Angular, for this reason, it doesn’t provide a routing by default, it let you decide which routing method to use: a library or to do it yourself. Here is where the Facebook team, that created React, would recommend you to use it’s react-router-dom
library, the one we’ll use now.
Starting a project
For the propose of this, we’ll make a SPA for a bookstore that will have three routes and a header:
/home
/books
/books/:slug
The Home page will have a welcome message. The Header will have a link to Home and to the Book’s page. In the Books page we’ll display a list of books with links that will redirect you to the Book description page (/books/:slug
) with mode details.
React allows you to create Single Page Applications (SPA) very easily using create-react-app
. I highly recommend using it as it has a lot of the configurations such as Babel and Webpack already set for you so that you won’t have to do it from scratch. Let’s do that:
npx create-react-app react-router-dom-essentials-book-example
Now, just cd react-router-dom-essentials-book-example
and we’ll add react-router-dom
to our dependencies.
npm install react-router-dom --save
# or
yarn add react-router-dom
We’ll focus on the functionality and we’ll leave the folder structure and moving the components to each file to another article for better understanding.
The initial routes.
To give the routing functionality to our application we need to wrap our main component inside a special component that react-router provides for us: <HashRouter/>
. Let’s open the src/App.js
file and set an initial setting to try things.
import { HashRouter, Switch, Route, Redirect, Link } from 'react-router-dom';
const Header = () => <h2>Header</h2>;
const Home = () => <h2>Home</h2>;
const Books = () => <h2>Books</h2>;
const BookItem = () => <h2>Book Item</h2>;
function App() {
return (
<div>
<HashRouter>
<Header/>
<Switch>
<Route exact path="/" render={Home} />
<Route exact path="/books/" component={Books} />
<Route path={"/books/:slug"} component={BookItem} />
<Redirect to="/" />
</Switch>
</HashRouter>
</div>
);
}
At this point, start the react application with yarn start
and check the following routes:
- http://localhost:3000/#/
- http://localhost:3000/#/books
- http://localhost:3000/#/books/harry-potter
- http://localhost:3000/#/this-does-not-match-anything-sam
You should see that a basic routing it’s already working showing you the three components. The last URL should redirect you to the home page as we set it like that for any URL that doesn’t match the ones we defined here.
HashRouter component
The first thing to notice is that we have everything wrapped inside HashRouter
to enable routing in those components.
The second thing to notice is the Switch
and the Route
components.
The Route component
The route component has three main properties:
exact
: define that the URL should match exactly thepath
.path
: the path in the URL to match.component
: the component to render if the path matches.
Why do we need
exact
exactly? simply put: Because if you don’t, it will render all the components in the routes that will partly match the URL.
For example, here are some URLs that match “…but not exactly” (exact
) are:
/books/categories/fiction
/books/categories/terror
/books/categories/historical
This means that they are sharing part of the path /books/categories/
.
Back to our example.
<Route exact path="/" component={Home} />
This will match “exactly” /
and render the Home
component only and will not render the rest.
The Switch component
The Switch component provides more control over the list of routes so that we don’t need to write the exact
property in all our routes, what it does is to render the first Route that matches the URL and it stops rendering the other components no matter if they have the exact
word or not. Is equivalent to place the exact
property in all the routes. It just gives you more control if you forget to use the exact
property.
The Redirect component
The redirect component allows us to redirect to a specific URL if there’s no match in the list of routes.
Until this point, you can check the progress in the initial-routes
branch in the example project.
More juice using Link
The link component allows us to navigate to the routes that we defined.
Let’s update the Header
, Books
and BookItem
component.
const Header = () => {
return(
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/books">Books</Link></li>
</ul>
)
}
const Books = () => {
return (
<div>
<h2>Books</h2>;
<ul>
<li>
<Link to={`/books/the-lord-of-the-rings`}>The Lord of the Rings</Link>
</li>
<li>
<Link to={`/books/harry-potter`}>Harry Potter</Link>
</li>
</ul>
</div>
)
}
const BookItem = ({ match }) => {
const slug = match.url.split('/')[2];
return (
<h2>Book Item {slug}</h2>
)
}
With all of these updates we should be able to have this result:
At this point, you can check the progress in the basic-navigation-with-link
branch in the example project.
The match
property is a special property that is passed to all components rendered directly in the Route
component and allows us to get the URL among other properties. In this case, we’re using it to the slug from the params in, for example, /books/the-lord-of-the-rings
.
I’ll end this article here because it’s already enough to get started. In a second part I’ll focus on folder structure and the use of the withRouter
component to use the math
, history
and location
property.
Did you like this article? would you like me to write more about other topics? please drop me a message or leave your comments down below, I’ll be more than happy to fix an issue that you found, constructive critics, suggestions, or to simply expand on these ideas.