React Router 路由与权限设计

SPA 路由设计:公开/受保护路由分组、ProtectedRoute 路由守卫、路径参数、token 过期处理。

#type / howto #status / growing #tech / dev / frontend #resource / react

[!info] related notes

React Router 路由与权限设计

路由分组

<BrowserRouter>
  <Routes>
    {/* 公开路由 */}
    <Route path="/login" element={<LoginPage />} />
    <Route path="/register" element={<RegisterPage />} />

    {/* 受保护路由 */}
    <Route path="/dashboard" element={
      <ProtectedRoute><DashboardPage /></ProtectedRoute>
    } />
    <Route path="/consultation/:id" element={
      <ProtectedRoute><ConsultationPage /></ProtectedRoute>
    } />

    {/* 默认重定向 */}
    <Route path="/" element={<Navigate to="/dashboard" replace />} />
  </Routes>
</BrowserRouter>

ProtectedRoute

function ProtectedRoute({ children }) {
  const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
  if (!isAuthenticated) return <Navigate to="/login" replace />;
  return <>{children}</>;
}

简单有效:已登录渲染子组件,未登录跳转登录页。

路径参数

<Route path="/consultation/:id" element={<ConsultationPage />} />

// 组件中
const { id } = useParams();

Token 过期处理

API 返回 401 时自动刷新 token,刷新失败则跳转登录:

api.interceptors.response.use(
  (res) => res,
  async (error) => {
    if (error.response?.status === 401) {
      const refreshed = await useAuthStore.getState().refreshAccessToken();
      if (!refreshed) {
        useAuthStore.getState().logout();
        window.location.href = '/login';
      }
    }
    return Promise.reject(error);
  },
);

SPA 刷新 404

nginx 配置:

location / {
    try_files $uri $uri/ /index.html;
}

所有未知路由都返回 index.html,由前端路由处理。

创建于 2026/6/25 更新于 2026/6/25