Core concepts of React Router v6 simplified

Arian Garshi
4 min readOct 26, 2023

--

With the introduction of React Router v6, the way we handle routing in React applications has been significantly improved. This article provides a brief introduction to the core concepts of the new Router to get you started on implementing it on your projects.

Routes & Route

Routes: This is a component that serves as a container for individual Route components. You can think of Routes as a switch mechanism that renders the first Route child that matches the current location.

Route: Represents an individual route in the application. It has two main props: path and element. The path is the URL pattern to match against, and the element is the React component that should be rendered for that path.

<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>

In the example above, we set up routes that connect the <Home />and <About /> Views. What is important to note here, is that this setup merely creates an association between the URL input of the browser and the visible components. It does not generate any tangible way of browsing the various paths within the application. For that, you need the <Link /> component

Nested Routes & Outlet

nested routes are established using the Routes component inside another route. This allows you to define child routes inside a parent route, and the parent route can use the Outlet component as a placeholder for where these child routes should render.

This concept may best be explained in a practical scenario. Imagine you’re building an admin dashboard with two primary sections: Users and Reports. The main dashboard page will have links to these sections, and clicking on them should change the content displayed while retaining the dashboard layout.

App.js

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Dashboard from './Dashboard';
import Users from './Users';
import Reports from './Reports';

function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/dashboard" element={<Dashboard />}>
<Route path="users" element={<Users />} />
<Route path="reports" element={<Reports />} />
</Route>
</Routes>
</BrowserRouter>
);
}

Dashboard.js

import { Outlet, Link } from 'react-router-dom';

function Dashboard() {
return (
<div>
<h1>Admin Dashboard</h1>
<nav>
<Link to="users">Users</Link> |
<Link to="reports">Reports</Link>
</nav>
<Outlet />
</div>
);
}

In this example,

  • When you navigate to /dashboard, you'll see the Dashboard component with links to Users and Reports.
  • The Outlet component inside Dashboard acts as a placeholder for nested routes.
  • Navigating to /dashboard/users will display the Users component within the Dashboard layout.
  • Similarly, navigating to /dashboard/reports will show the Reports component within the Dashboard.

Worth noting, is that the JSX before Outlet is present in both child routes. This makes creating dashboards mixing persistent and dynamic content very intuitive.

Link

The Link component allows users to navigate between different routes. It generates an anchor (<a>) tag underneath, but does so in a way that doesn't cause a full page reload, preserving the single-page application behavior.

<Link to="/about">About Us</Link>

In the example above, we have now created a clickable text element in our DOM. This can be placed anywhere in your web app and navigates the user to the <About /> View when they click on it.

This approach of directing traffic around a web app is preferred for static navigation, like nav menus, breadcrumbs, or inline links in text. When rendered, they generate anchor tags that are SEO-friendly in the sense that they let web crawlers navigate and index the app with ease.

useNavigate

useNavigate is a hook that returns a function that when called, navigates to a specified route. It is a programmatic alternative to the more static alternative, Link .

import { useNavigate } from 'react-router-dom';

function LoginForm() {
const navigate = useNavigate();

const handleLogin = async (credentials) => {
const user = await loginUser(credentials);

if (user.role === 'admin') {
navigate('/admin/dashboard');
} else {
navigate(`/user/${user.id}`);
}
}

return (
// Your form JSX...
);
}

The example above shows how we can use this hook to conditionally navigate to different routes based on the users role. If they are an admin, they are sent to one page, while if they are a regular user, they are sent to another. All without needing any additional input from the user.

Additionally, this hook is a great way of implementing a “go back” button.

function BackButton() {
const navigate = useNavigate();

return (
<button onClick={() => navigate(-1)}>Go Back</button>
);
}

It lets users navigate back in the history stack using a negative number as the argument. This is specially great in terms of UX, as it takes the user back to wherever they came from. Even if they came from an entirely different website, when they click on this button, they will go back to the previous site.

Another scenario where useNavigate shines is protected routes. you may for instance want to redirect the user somewhere else if a condition is not met when they access a route.

Conclusion

The new version of React Router has overhauled and simplified how routing works for directing traffic across the components. In this article we looked at the various main concepts of the new React router, with the aim of learning the essentials needed to get started implementing the technology in any web app.

--

--

Arian Garshi
Arian Garshi

Written by Arian Garshi

Software engineer & UX-designer

No responses yet