React Router 路由与权限设计
SPA 路由设计:公开/受保护路由分组、ProtectedRoute 路由守卫、路径参数、token 过期处理。
#type / howto
#status / growing
#tech / dev / frontend
#resource / react
[!info] related notes
- 状态: Zustand 全局状态
- 结构: Feature-Based 目录结构
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,由前端路由处理。