You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router 6自定义受保护路由:替代Redirect的实现方案

React Router 6 受保护路由实现修正

错误原因

React Router 6 对 <Routes> 的子组件有严格要求:只能是 <Route> 或 <React.Fragment>,不能直接放置自定义组件。同时RR6移除了Route的component、render props,统一改用element属性传递组件。

步骤1:修正App.js的路由配置

把原来的component替换为element,并将ProtectedRoutes作为<Route>的element值传入,而非直接作为Route组件使用:

function App() {
  return (
    <Container>
      <Row>
        <Col className="text-center">
          <h1>React Authentication Tutorial</h1>

          <section id="navigation">
            <a href="/">Home</a>
            <a href="/free">Free Component</a>
            <a href="/auth">Auth Component</a>
          </section>
        </Col>
      </Row>

      <Routes>
        <Route path="/" element={<Account />} />
        <Route path="/free" element={<FreeComponent />} />
        {/* 将ProtectedRoutes作为element传入,内部包裹需要保护的组件 */}
        <Route 
          path="/auth" 
          element={
            <ProtectedRoutes>
              <AuthComponent />
            </ProtectedRoutes>
          } 
        />
      </Routes>
    </Container>
  );
}

步骤2:重写ProtectedRoutes组件

RR6中不再使用render或component props,而是通过组件嵌套+useLocation钩子获取当前路由信息,同时用Navigate替代Redirect:

import React from "react";
import { Navigate, useLocation } from "react-router-dom";
import Cookies from "universal-cookie";
const cookies = new Cookies();

export default function ProtectedRoutes({ children }) {
  const location = useLocation();
  const token = cookies.get("TOKEN");

  if (token) {
    // 已登录,渲染受保护的子组件
    return children;
  } else {
    // 未登录,重定向到首页,并记录原本要访问的路径
    return (
      <Navigate
        to="/"
        replace
        state={{ from: location }}
      />
    );
  }
}

额外优化建议

  • 把导航栏的<a>标签替换为RR6的<Link>组件,避免页面整体刷新:
    import { Link } from "react-router-dom";
    
    // 替换后
    <section id="navigation">
      <Link to="/">Home</Link>
      <Link to="/free">Free Component</Link>
      <Link to="/auth">Auth Component</Link>
    </section>
    
  • 如果需要批量保护多个路由,可以用Outlet实现嵌套路由的批量保护:
    // App.js
    <Routes>
      <Route path="/" element={<Account />} />
      <Route path="/free" element={<FreeComponent />} />
      {/* 批量保护/auth下的所有子路由 */}
      <Route element={<ProtectedRoutes />}>
        <Route path="/auth" element={<AuthComponent />} />
        <Route path="/auth/profile" element={<UserProfile />} />
      </Route>
    </Routes>
    
    // ProtectedRoutes.js 调整为用Outlet
    export default function ProtectedRoutes() {
      const location = useLocation();
      const token = cookies.get("TOKEN");
    
      if (token) {
        return <Outlet />;
      } else {
        return <Navigate to="/" replace state={{ from: location }} />;
      }
    }
    

内容的提问来源于stack exchange,提问作者Rachel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:24:57