react实现路由拦截
路由拦截的实现方法
在React中实现路由拦截通常通过高阶组件或自定义钩子完成,以下是几种常见方法:
使用React Router的<Navigate>组件
利用React Router v6的<Navigate>组件进行重定向,结合条件判断实现拦截逻辑:
import { Navigate, useLocation } from 'react-router-dom';
const PrivateRoute = ({ children }) => {
const isAuthenticated = checkAuth(); // 自定义认证逻辑
const location = useLocation();
if (!isAuthenticated) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
};
// 使用方式
<Route path="/dashboard" element={
<PrivateRoute>
<Dashboard />
</PrivateRoute>
} />
自定义路由守卫组件
创建路由守卫组件封装拦截逻辑,适用于需要统一处理权限的场景:
const RouteGuard = ({ component: Component, ...rest }) => {
const hasPermission = checkPermissions(rest.path);
return hasPermission ? (
<Component {...rest} />
) : (
<div>无权限访问</div>
);
};
// 路由配置
<Routes>
<Route path="/admin" element={<RouteGuard component={AdminPage} />} />
</Routes>
使用路由配置拦截
在路由配置阶段预处理拦截逻辑,适用于静态路由配置:
const routes = [
{
path: '/profile',
element: <Profile />,
beforeEnter: () => {
if (!isLoggedIn()) {
return '/login';
}
return true;
}
}
];
const RouterWithInterceptor = () => {
const element = useRoutes(routes.map(route => {
if (route.beforeEnter) {
const result = route.beforeEnter();
if (result !== true) {
return { ...route, element: <Navigate to={result} replace /> };
}
}
return route;
}));
return element;
};
使用useEffect监听路由变化
在页面组件内通过useEffect监听路由变化实现拦截:
const ProtectedPage = () => {
const navigate = useNavigate();
useEffect(() => {
const token = localStorage.getItem('token');
if (!token) {
navigate('/login', { replace: true });
}
}, [navigate]);
return <div>受保护内容</div>;
};
权限验证高阶组件
创建高阶组件包装需要拦截的组件,实现复用:
const withAuth = (WrappedComponent) => {
return (props) => {
const [verified, setVerified] = useState(false);
const navigate = useNavigate();
useEffect(() => {
const verify = async () => {
const isValid = await verifyToken();
if (!isValid) {
navigate('/auth-error');
}
setVerified(true);
};
verify();
}, [navigate]);
return verified ? <WrappedComponent {...props} /> : <LoadingSpinner />;
};
};
// 使用方式
const EnhancedComponent = withAuth(SensitiveComponent);
注意事项
- 异步验证时需处理加载状态
- 记住原始路由以便登录后跳转
- 服务端渲染场景需考虑服务端验证
- 路由拦截可能影响浏览器历史记录
以上方法可根据实际项目需求组合使用,React Router v6的拦截实现更倾向于组件化方式,相比v5有更明确的API设计。







