Home >Web Front-end >JS Tutorial >How to Implement Protected Routes in React Router v5 and v6?
<BrowserRouter> <Switch> {authLogin ? ( <> <Route path="/dashboard" component={Dashboard} exact /> <Route exact path="/About" component={About} /> </> ) : ( <Route path="/" component={Login} exact /> )} <Route component={PageNotFound} /> </Switch> </BrowserRouter>
The Switch doesn't handle rendering anything other than Route and Redirect components. If you want to "nest" like this then you need to wrap each in generic routes, but that is completely unnecessary.
Your login component also doesn't handle redirecting back to any "home" page or private routes that were originally being accessed.
In version 6 custom route components have fallen out of favor, the preferred method is to use an auth layout component.
import { Navigate, Outlet } from 'react-router-dom'; const PrivateRoutes = () => { const location = useLocation(); const { authLogin } = useContext(globalC); if (authLogin === undefined) { return null; // or loading indicator/spinner/etc } return authLogin ? <Outlet /> : <Navigate to="/login" replace state={{ from: location }} />; }
...
<BrowserRouter> <Routes> <Route path="/" element={<PrivateRoutes />} > <Route path="dashboard" element={<Dashboard />} /> <Route path="about" element={<About />} /> </Route> <Route path="/login" element={<Login />} /> <Route path="*" element={<PageNotFound />} /> </Routes> </BrowserRouter>
or
const routes = [ { path: "/", element: <PrivateRoutes />, children: [ { path: "dashboard", element: <Dashboard />, }, { path: "about", element: <About /> }, ], }, { path: "/login", element: <Login />, }, { path: "*", element: <PageNotFound /> }, ];
...
export default function Login() { const location = useLocation(); const navigate = useNavigate(); const { authLogin, loginData } = useContext(globalC); useEffect(() => { if (authLogin) { const { from } = location.state || { from: { pathname: "/" } }; navigate(from, { replace: true }); } }, [authLogin, location, navigate]); return ( <div >
Create a PrivateRoute component that consumes your auth context.
const PrivateRoute = (props) => { const location = useLocation(); const { authLogin } = useContext(globalC); if (authLogin === undefined) { return null; // or loading indicator/spinner/etc } return authLogin ? ( <Route {...props} /> ) : ( <Redirect to={{ pathname: "/login", state: { from: location } }} /> ); };
Update your Login component to handle redirecting back to the original route being accessed.
export default function Login() { const location = useLocation(); const history = useHistory(); const { authLogin, loginData } = useContext(globalC); useEffect(() => { if (authLogin) { const { from } = location.state || { from: { pathname: "/" } }; history.replace(from); } }, [authLogin, history, location]); return ( <div >
Render all your routes in a "flat list"
function Routes() { return ( <BrowserRouter> <Switch> <PrivateRoute path="/dashboard" component={Dashboard} /> <PrivateRoute path="/About" component={About} /> <Route path="/login" component={Login} /> <Route component={PageNotFound} /> </Switch> </BrowserRouter> ); }
The above is the detailed content of How to Implement Protected Routes in React Router v5 and v6?. For more information, please follow other related articles on the PHP Chinese website!