React Router v6 is a popular and powerful routing library for React applications. It provides aDeclarative, component-based routing method,andAble to handle common tasks such as URL parameters, redirection and loading data。
This latest version of React Router introduces many new concepts, such as<Outlet />
andlayout
Layout routes, but there is still little related documentation.
This article will demonstrate how to use itReact Router v6
Create protected routes and how to add authentication.
start
Open the terminal and run the following command to create a new React project:
> npx create-react-app ReactRouterAuthDemo > cd ReactRouterAuthDemo
Next, install it in the React applicationReact Router
As a dependency:
> npm install react-router-dom
Once the React Router dependencies are installed, we can start editingsrc/
document.
First, fromreact-router-dom
Import inBrowserRouter
Components, then use<BrowserRouter />
pack<App />
Components, like this:
import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; import App from "./App"; const rootElement = ("root"); const root = createRoot(rootElement); ( <StrictMode> <BrowserRouter> <App /> </BrowserRouter> </StrictMode> );
Basic routing
React Router provides<Routes />
and<Route />
Components, which enables us to render them according to the current location of the components.
import { Routes, Route } from "react-router-dom"; import { LoginPage } from "./pages/Login"; import { HomePage } from "./pages/Home"; import "./"; export default function App() { return ( <Routes> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> </Routes> ); }
<Route />
Provides a mapping of paths between the application and React components. For example, when the user navigates to/login
When renderingLoginPage
Components, we just need to provide them like this<Route />
:
<Route path="/login" element={<LoginPage />} />
<Route />
The component can be regarded as aif
Statement, only when the element matches the specified path, it will act onURL
location.
<Routes />
The component isReact Router v5
In-house<Switch />
Component alternative.
We can createand
Come to use
<Routes />
:
// export const LoginPage = () => ( <div> <h1>This is the Login Page</h1> </div> ); // export const HomePage = () => ( <div> <h1>This is the Home Page</h1> </div> );
Next, we will run the following command to start the application:
> npm run start
In the browser, we will see by defaultHome
Components. If we use/login
Routing, we will seeLoginPage
The component is rendered on the screen.
Alternatively, we can also use a normal JavaScript object, throughuseRoutes
Hook to represent routes in the application. This is a functional method to define routing, and its working method is< routes />
and<Route />
The components are the same.
import { useRoutes } from "react-router-dom"; // ... export default function App() { const routes = useRoutes([ { path: "/", element: <HomePage /> }, { path: "/login", element: <LoginPage /> } ]); return routes; }
Now that the basic setup is complete, let's see how to create a protected route so that unauthenticated users cannot access certain content in the application.
Create protected routes
Before creating a protected route, let's create a custom hook that will useContext API
anduseContext
The hook handles the status of the authenticated user.
import { createContext, useContext, useMemo } from "react"; import { useNavigate } from "react-router-dom"; import { useLocalStorage } from "./useLocalStorage"; const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [user, setUser] = useLocalStorage("user", null); const navigate = useNavigate(); // When verifying user permissions, access this function const login = async (data) => { setUser(data); navigate("/profile"); }; // Sign out const logout = () => { setUser(null); navigate("/", { replace: true }); }; const value = useMemo( () => ({ user, login, logout }), [user] ); return < value={value}>{children}</>; }; export const useAuth = () => { return useContext(AuthContext); };
The aboveuseAuth
In the hook, we expose the user's status and some methods for user login and logout. When the user logs out, we useReact Router
ofuseNavigate
Hook to bring themRedirectGo to the home page.
To keep the user's status while the page is refreshed, we will useuseLocalStorage
Hook, which will synchronize the status values in the browser's local storage.
import { useState } from "react"; export const useLocalStorage = (keyName, defaultValue) => { const [storedValue, setStoredValue] = useState(() => { try { const value = (keyName); if (value) { return (value); } else { (keyName, (defaultValue)); return defaultValue; } } catch (err) { return defaultValue; } }); const setValue = (newValue) => { try { (keyName, (newValue)); } catch (err) {} setStoredValue(newValue); }; return [storedValue, setValue]; };
<ProtectedRoute />
The component will be fromuseAuth
Check the status of the current user in the hook, if the user is not authenticated, redirect to/
path.
import { Navigate } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const ProtectedRoute = ({ children }) => { const { user } = useAuth(); if (!user) { // user is not authenticated return <Navigate to="/" />; } return children; };
To redirect users, we use<Navigate />
Components. When the parent component renders the current location,<Navigate />
The component changes the current position. It is used internallyusenavate
hook.
existIn the file, we can use
<ProtectedRoute />
Component packagingpage
Components. For example, we use<ProtectedRoute />
Package<SettingsPage />
and<ProfilePage />
Components. Now, when an unauthenticated user tries to access/profile
or/settings
When paths are made, they will be redirected to the home page.
import { Routes, Route } from "react-router-dom"; import { LoginPage } from "./pages/Login"; import { HomePage } from "./pages/Home"; import { SignUpPage } from "./pages/SignUp"; import { ProfilePage } from "./pages/Profile"; import { SettingsPage } from "./pages/Settings"; import { ProtectedRoute } from "./components/ProtectedRoute"; export default function App() { return ( <Routes> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> <Route path="/register" element={<SignUpPage />} /> <Route path="/profile" element={ <ProtectedRoute> <ProfilePage /> </ProtectedRoute> } /> <Route path="/settings" element={ <ProtectedRoute> <SettingsPage /> </ProtectedRoute> } /> </Routes> ); }
The above method works well if the number of protected routes is limited, but if there are multiple such routes, we have to wrap each one, which is cumbersome.
Instead, we can use React Router v6'sNested routing features,Encapsulate all protected routes in one layout.
Using nested routing and <Outlet />
React Router v6One of the most powerful features is nested routing. This feature allows us to have aRouters containing other subroutines. Most of our layouts are coupled to fragments on the URL, and React Router fully supports this.
For example, we can<HomePage />
and<LoginPage />
Add a parent component to the route<Route />
, like this:
import { ProtectedLayout } from "./components/ProtectedLayout"; import { HomeLayout } from "./components/HomeLayout"; // ... export default function App() { return ( <Routes> <Route element={<HomeLayout />}> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> </Route> <Route path="/dashboard" element={<ProtectedLayout />}> <Route path="profile" element={<ProfilePage />} /> <Route path="settings" element={<SettingsPage />} /> </Route> </Routes> ); }
Parent component<Route />
There can also be a path that is responsible for rendering child components on the screen<Route />
。
When the user navigates to/dashboard/profile
When the router will render<ProfilePage />
. To achieve this, the parent route element must have a<Outlet />
Component to render child elements.Outlet
Components make nested UI visible when rendering subroutines.
The parent routing element may also have additional public business logic and user interface. For example,<ProtectedLayout />
In the component, we already include the private routing logic and a general navigation bar that will be visible when the subroutine is rendered.
import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const ProtectedLayout = () => { const { user } = useAuth(); if (!user) { return <Navigate to="/" />; } return ( <div> <nav> <Link to="/settings">Settings</Link> <Link to="/profile">Profile</Link> </nav> <Outlet /> </div> ) };
Apart from<Outlet />
Components, we can also choose to useuseOutlet
Hook, its function is the same:
import { Link, Navigate, useOutlet } from "react-router-dom"; // ... export const ProtectedLayout = () => { const { user } = useAuth(); const outlet = useOutlet(); if (!user) { return <Navigate to="/" />; } return ( <div> <nav> <Link to="/settings">Settings</Link> <Link to="/profile">Profile</Link> </nav> {outlet} </div> ); };
Similar to protected routes, we do not want authenticated users to access/login
path. Let's be<HomeLayout />
Process it in the component:
import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const HomeLayout = () => { const { user } = useAuth(); if (user) { return <Navigate to="/dashboard/profile" />; } return ( <div> <nav> <Link to="/">Home</Link> <Link to="/login">Login</Link> </nav> <Outlet /> </div> ) };
Ending
It's worth taking some time to better understand how React Router v6 works, especially user authentication.
React Router v6 is a huge improvement compared to previous versions. It is fast, stable and reliable. Besides being easier to use, it has many new features, such as<Outlets />
and an improved<Route />
Components, this greatly simplifies routing in React applications.
I hope this guide helps you and hope you have a better understanding of how to handle user authentication using React Router v6.
This is the article about using React Router v6 for authentication. This is all about this article. For more relevant React Router v6 verification content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!