With approximately 3.6 million downloads on npm, React Router is one of the most popular libraries for React. Used for building interfaces, it is a fully-featured client and server-side routing library.
In a Single-Page Application (SPA), instead of reloading entire pages from a server, only some sections are rewritten. This powerful library allows you to navigate among the views of various components in a React application. It changes the browser URL while keeping the UI on track with it.
In September 2021, with the release of React-Router V6 came several improvements and significant syntax changes. One significant change is the bundle size which is 60% smaller than those in React-Router V5, resulting in much quicker load times.
In this guide I’m going to talk about the most important changes, giving a step-by-step guide on how to migrate your project to the newest version.
Installing React-Router is very straightforward. After creating your react app, inside your root folder, run:
{% code-block language="js" %}
npm install react-router-dom@6
{% code-block-end %}
If you are completely new to React, you can check React’s documentation for more details on how to set up your app.
You can also check out the Introduction to ReactJS published on our blog to understand React basics.
The different pages in your application are different components that will render whatever you decide to code. There are no rules for the location of files. To keep things organized, in this example, I’ll keep the following structure:
Now that we have all our files, we need to set up our routes. In React-Router V5, the routing configuration was done by having a <Switch> which wrapped <Route>s with their respective child components, like the following:
{% code-block language="js" %}
<Switch>
<Redirect exact from="/" to="/home" />
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/home">
<Home />
</Route>
</Switch> {% code-block-end %}
In React-Router V6, we no longer have a <Switch> component. We set up routes with a <Routes> wrapper, with <Route>s components passing their path prop and respective components as an element, as follows:
{% code-block language="js" %}
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="users" element={<Users />} />
</Routes> {% code-block-end %}
It is also important to mention that the new React-Router V6 does not accept anything but a <Route> inside the <Routes> wrapper. In the case of switching React-Router V5 to V6 for instance, if you simply swapped the <Switch> wrapper with <Routes>, it would compile, but wouldn’t display anything.
With the release of React-Router V6, the usage of <Switch> will result in the following error:
{% code-block language="js" %} Attempted import error: 'Switch' is not exported from 'react-router-dom' (imported as 'Switch').
ERROR in ./src/index.js 13:33-39
export 'Switch' (imported as 'Switch') was not found in 'react-router-dom' (possible exports: BrowserRouter, HashRouter, Link, MemoryRouter, NavLink, Navigate, NavigationType, Outlet, Route, Router, Routes, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, createPath, createRoutesFromChildren, createSearchParams, generatePath, matchPath, matchRoutes, parsePath, renderMatches, resolvePath, unstable_HistoryRouter, useHref, useInRouterContext, useLinkClickHandler, useLocation, useMatch, useNavigate, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useSearchParams) {% code-block-end %}
It is also significant to mention that the same applies to the <Redirect> component. So if you ever find yourself with this compiling error, double-check whether the component exists or not in the version you are currently using.
The 404 page is a no-match page that will be used when the user tries to navigate to a non-existing path. First things first, you need to create a component that will display your message error, or image, like so:
Setting up a no match page is pretty straightforward in both React-Router V5 and React-Router V6. In older versions of React-Router, just like the other Switch/Route routes, your <NoMatch> component will be wrapped inside a <Route>, without a path prop:
{% code-block language="js" %}
<Route>
<NoMatch />
</Route> {% code-block-end %}
For the latest version, it is also necessary to have a <NoMatch /> component, but we use the new element prop, as well as the following path:
{% code-block language="js" %}
<Route path="*" element={<NoMatch />} />
{% code-block-end %}
Now that we have all our routes and paths, it’s time to set a way to navigate through them. The most common way is to have a header with links to their respective routes/paths.
The syntax is the same for both React-Router V5 and React-Router V6, you just need <Link>s with “to” props pointing to their respective routes. To keep the HTML semantic, it is a good practice to keep them wrapped in a <Nav> tag:
{% code-block language="js" %}
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="/about">About</Link> |{" "}
<Link to="/users">Users</Link>
</nav>
{% code-block-end %}
Yes! It is also possible to style the navigation links when the current one is accessed or “active”. This can be done with a special kind of <Link> called a <NavLink>.
To do so, you can pass a function to a style or className, if you are using a front-end framework, for instance, that will allow inline styling to the link based on its active state. One of the easiest ways to do this is by creating a variable to store your inline styling and using a ternary operator:
{% code-block language="js" %} import * as React from "react";
import { NavLink } from "react-router-dom";
function NavList() {
let activeStyle = {
fontWeight: ‘bold’,
color: ‘green’
};
let activeClassName = "fw-bold text-success";
return (
<nav>
<NavLink
to="/"
style={ ({ isActive }) => isActive? activeStyle: undefined }
>
Home
</NavLink> |{" "}
<NavLink
to="/about"
className={ ({ isActive }) => isActive ? activeClassName : undefined }
>
About
</NavLink> |{" "}
<NavLink to="/users">
{({ isActive }) => (
<span className={ isActive ? activeClassName : undefined }>
Tasks
</span>
)}
</NavLink>
</nav>
)}; {% code-block-end %}
If you want to learn more about React and software development, learn how to get set up with React/Redux in your next multi-page project.
Career advice, the latest coding trends and languages, and insights on how to land a remote job in tech, straight to your inbox.