Route to different pages in the application
In this chapter, you will use the react-router-dom to manage your routes and navigate to different pages using a navigation bar component.
Software Engineering Team Lead and Director of Cloudsure
Objectives
- Add routes to each page in order to navigate to them.
- Create a navigation bar to render links for pages.
Dependency
You need to install an npm package called react-router-dom that will manage your routes in React for you.
npm install react-router-dom
React Router is seemingly the most popular way to add page routing in React Apps. The video below offers:
- A crash course for beginners.
- Learning how to use React Router v6.
Create routes
You'll import a few things from react-router-dom
.
Checkout the docs to find out more about each one.
You'll also be importing all the pages you need routes for.
Your routing will be hooked up in index.js
.
Each path is a route and it will render an element to render
corresponding to a page when matched on.
The path /*
matches on any path and will render the NotFoundPage
if that match does not match on any of the other
Route paths specified.
:slug
is a param in the URL segment that allows for variable content
that we can access programmatically.
// ... other imports
import {
Route,
RouterProvider,
createBrowserRouter,
createRoutesFromElements,
} from "react-router-dom";
import HomePage from './pages/Home';
import RegisterPage from './pages/Register';
import LoginPage from './pages/Login';
import ReviewPage from './pages/Review';
import NotFoundPage from './pages/NotFound';
const router = createBrowserRouter(
createRoutesFromElements(
<Route>
<Route path="/" element={<HomePage />} />
<Route path="/*" element={<NotFoundPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/review/:slug" element={<ReviewPage />} />
</Route>
)
);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Layout>
<RouterProvider
router={router}
fallbackElement={<div>Loading....</div>}
/>
</Layout>
</React.StrictMode>,
);
// ... other code
You no longer need the App
files so you can safely remove them.
rm src/App.*
Navigation
You will want to navigate to the different pages that you have created.
In order to do so, create a navigation component with links to the different pages in it
using the react-router-dom
package.
touch src/components/Navigation.js
import { Link } from 'react-router-dom';
const Navigation = () => {
return (
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/register">Register</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
</ul>
</nav>
);
};
export default Navigation;
The Navigation component uses the routes so it needs context to the RouterProvider
.
Change the Layout component to make render Outlet
instead of the former children
prop.
Use Outlet to render the element
component associated with the path specified in index.js
.
import { Outlet } from 'react-router-dom';
import Navigation from './Navigation';
const Layout = () => {
return (
<div>
<Navigation />
<Outlet />
</div>
);
};
export default Layout;
The Navigation component relies on the RouterProvider in order to render correctly. Right now it's outside the provider.
Let's wrap the page inside the Layout component within the provider. Update the route element to render the Layout component and remove the Layout wrapper on RouterProvider.
// ....
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<Layout />}>
<Route path="/" element={<HomePage />} />
<Route path="*" element={<NotFoundPage />} />
<Route path="register" element={<RegisterPage />} />
<Route path="login" element={<LoginPage />} />
<Route path="review/:slug" element={<ReviewPage />} />
</Route>,
),
);
// ....
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router} fallbackElement={<div>Loading....</div>} />
</React.StrictMode>,
);
// ...
URL params
Create a fake in-memory data file for the interim. This data will be displayed in our app for the interim.
mkdir src/data && touch src/data/reviews.json
Populate the file with random data.
[
{
"slug": "1",
"title": "Joe's Snack Shop",
"abstract": "Lorem ipsum, dolor sit amet consectetur adipisicing elit.",
"rating": 3.5
},
{
"slug": "2",
"title": "Gerry's TV",
"abstract": "Lorem ipsum, dolor sit amet consectetur adipisicing elit.",
"rating": 4.5
},
{
"slug": "3",
"title": "Pieter's Flower Shack",
"abstract": "Lorem ipsum, dolor sit amet consectetur adipisicing elit.",
"rating": 4.5
}
]
Display the data in the Reviews page based on the URL. Render the Not Found page when there is no match on the data.
import { useParams } from 'react-router-dom';
import NotFoundPage from './NotFound';
import data from '../data/reviews.json';
const ReviewPage = () => {
const { slug } = useParams();
const reviews = data.filter((i) => i.slug === slug);
if (reviews.length > 0) {
const review = reviews[0];
return (
<div>
Review page <pre>{JSON.stringify(review, null, 2)}</pre>
</div>
);
}
return <NotFoundPage />;
};
export default ReviewPage;
Listing
Show all reviews on the home page and link through to the correct review page.
import { Link } from 'react-router-dom';
import data from '../data/reviews.json';
const HomePage = () => {
return data.map(({ slug, title, description, rating }) => {
return (
<div key={slug}>
<h2>
<Link to={`/review/${slug}`}>{title}</Link> / {rating} ✨
</h2>
<p>{description}</p>
</div>
);
});
};
export default HomePage;
Next steps
You will create a backend API that will contain logic to authenticate, rate and comment on things.
References
- react-router-dom - Official documentation
- React Router 6 - Tutorial for Beginners - freeCodeCamp.org on YouTube
- <Outlet /> component - Official documentation