react如何进行路由拦截
React 路由拦截的实现方法
React 中实现路由拦截通常依赖路由库(如 React Router),通过高阶组件、自定义路由组件或导航守卫等方式控制访问权限。以下是几种常见方法:
使用高阶组件(HOC)包装路由
创建一个高阶组件,用于检查用户权限或登录状态,决定是否渲染目标组件或重定向到其他路由:
import { Redirect, Route } from 'react-router-dom';
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
<Route
{...rest}
render={(props) =>
isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
// 使用示例
<PrivateRoute path="/dashboard" isAuthenticated={userLoggedIn} component={Dashboard} />
自定义 <Route> 组件
通过扩展 <Route> 组件,在 render 方法中添加拦截逻辑:
const AuthRoute = ({ path, condition, redirectPath, children }) => {
return (
<Route path={path}>
{({ location }) =>
condition ? (
children
) : (
<Redirect to={{ pathname: redirectPath, state: { from: location } }} />
)
}
</Route>
);
};
// 使用示例
<AuthRoute path="/admin" condition={isAdmin} redirectPath="/no-access">
<AdminPage />
</AuthRoute>
使用 React Router v6 的 <Navigate> 组件
React Router v6 推荐使用 <Navigate> 和 useNavigate 实现拦截:
import { Navigate, Outlet } from 'react-router-dom';
const ProtectedRoute = ({ isAllowed, redirectPath = '/login' }) => {
if (!isAllowed) {
return <Navigate to={redirectPath} replace />;
}
return <Outlet />;
};
// 在路由配置中使用
<Route element={<ProtectedRoute isAllowed={isUserLoggedIn} />}>
<Route path="/profile" element={<Profile />} />
</Route>
全局导航拦截
通过监听路由变化,在全局范围内统一处理拦截逻辑(适用于 React Router v5/v6):
import { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
const useAuthGuard = (shouldBlock, redirectPath) => {
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
if (shouldBlock(location)) {
navigate(redirectPath, { replace: true, state: { from: location } });
}
}, [location]);
};
// 在组件中调用
useAuthGuard(
(loc) => !userToken && loc.pathname.startsWith('/app'),
'/auth'
);
结合 Context 或状态管理
将权限状态存储在全局上下文(如 Context API)或状态库(如 Redux),动态控制路由拦截:
const AuthContext = createContext();
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
return (
<AuthContext.Provider value={{ user }}>
{children}
</AuthContext.Provider>
);
};
// 在拦截组件中消费上下文
const { user } = useContext(AuthContext);
const isAdmin = user?.role === 'admin';
关键注意事项
- 路由库版本差异:React Router v5 和 v6 的 API 设计不同,需根据版本选择对应方法。
- 状态持久化:登录状态通常需持久化(如 localStorage),避免刷新后失效。
- 动态权限:对于动态权限(如角色权限),建议在拦截时实时校验而非仅依赖初始化状态。
通过以上方法,可以灵活实现登录验证、角色权限控制、功能开关等路由拦截场景。







