跳到主要内容

路由守卫

一、全局守卫

数据路由 + 加载器守卫
import { createBrowserRouter, RouterProvider } from 'react-router';

// 加载器函数实现守卫
const router = createBrowserRouter([
{
path: '/',
element: <Layout />,
children: [
{
path: 'dashboard',
element: <Dashboard />,
loader: async () => {
// 检查认证
const isAuthenticated = await checkAuth();
if (!isAuthenticated) {
throw new Response('Unauthorized', {
status: 401,
statusText: '需要登录',
});
}
return null;
},
},
{
path: 'admin',
element: <AdminPanel />,
loader: async () => {
const user = await getCurrentUser();
if (user?.role !== 'admin') {
throw new Response('Forbidden', {
status: 403,
});
}
return { user };
},
},
],
},
{
path: '/login',
element: <Login />,
},
{
path: '*',
element: <NotFound />,
},
]);

function Root() {
return <RouterProvider router={router} fallbackElement={<Loading />} />;
}

二、局部守卫

import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';

function Dashboard() {
const history = useHistory();
const isAuthenticated = true; // 从状态管理处获取

useEffect(() => {
if (!isAuthenticated) {
history.replace('/login');
}
}, [isAuthenticated, history]);
}
return <div>仪表盘</div>;

三、 404 页面

数据路由 + 加载器守卫
import { createBrowserRouter, RouterProvider } from 'react-router';

// 加载器函数实现守卫
const router = createBrowserRouter([
{
path: '/login',
element: <Login />,
},
{
path: '*',
element: <NotFound />,
},
]);

function Root() {
return <RouterProvider router={router} fallbackElement={<Loading />} />;
}

四、 v7 版本的错误边界处理

import { useRouteError, isRouteErrorResponse } from 'react-router';

function ErrorBoundary() {
const error = useRouteError();
if (isRouteErrorResponse(error)) {
switch (error.status) {
case 401:
return <Navigate to="/login" replace />;
case 403:
return <Unauthorized />;
case 404:
return <NotFound />;

default:
return <ErrorPage />;
}
}

return <ErrorPage />
}

// 在路由中使用
{
path: '/protected',
element: <ProtectedPage />,
loader: protectedLoader,
errorElement: <ErrorBoundary />
}