react如何做全局路由拦截
在React中实现全局路由拦截通常需要结合路由库(如React Router)和状态管理工具。以下是几种常见方法:
使用React Router的Navigate组件
在React Router v6中,可以通过Navigate组件和useNavigate钩子实现路由拦截。创建一个高阶组件包裹需要保护的路由:

import { Navigate, useLocation } from 'react-router-dom';
const PrivateRoute = ({ children }) => {
const location = useLocation();
const isAuthenticated = checkAuth(); // 自定义认证逻辑
return isAuthenticated
? children
: <Navigate to="/login" state={{ from: location }} replace />;
};
// 使用方式
<Route path="/protected" element={<PrivateRoute><ProtectedPage /></PrivateRoute>} />
使用路由守卫组件
创建一个路由守卫组件统一处理所有路由跳转:
import { Routes, Route, useLocation, Navigate } from 'react-router-dom';
const RouterGuard = ({ children }) => {
const location = useLocation();
const authRoutes = ['/dashboard', '/profile'];
if (authRoutes.includes(location.pathname) && !isLoggedIn()) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
};
// 在根组件中使用
<RouterGuard>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</RouterGuard>
使用自定义history对象
通过创建自定义history对象实现全局控制:

import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
history.listen((location, action) => {
if (requiresAuth(location.pathname) && !isAuthenticated()) {
history.push('/login', { from: location });
}
});
// 在Router中使用
<Router location={history.location} navigator={history}>
{/* routes */}
</Router>
结合Context API
对于需要深度集成的场景,可以结合Context管理路由状态:
const AuthContext = createContext();
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const checkAccess = (path) => {
if (path.startsWith('/admin') && !user?.isAdmin) {
return false;
}
return true;
};
return (
<AuthContext.Provider value={{ user, checkAccess }}>
{children}
</AuthContext.Provider>
);
};
// 在组件中使用useContext(AuthContext)获取状态
路由配置集中管理
通过集中式路由配置实现统一拦截:
const routes = [
{
path: '/',
element: <Home />,
public: true
},
{
path: '/admin',
element: <Admin />,
middleware: [authMiddleware, adminMiddleware]
}
];
const renderRoutes = (routes) => (
<Routes>
{routes.map((route) => (
<Route
key={route.path}
path={route.path}
element={<MiddlewareWrapper route={route} />}
/>
))}
</Routes>
);
每种方法适用于不同场景,简单项目可使用高阶组件方案,复杂项目建议采用集中路由配置或自定义history方案。注意在拦截时保留原始路由状态以便登录后重定向。






