v6路由数据保护踩坑记录
最近在将项目从React Router v5升级到v6时,遇到了一个令人头疼的问题:路由数据保护。在v6中,<Route>组件的component属性被移除,改用element属性来渲染组件,这导致原有的保护逻辑需要重新实现。
问题重现
在v5中,我们通常这样写保护路由:
<Route path="/dashboard" component={Dashboard} />
但在v6中,必须改为:
<Route path="/dashboard" element={<Dashboard />} />
核心问题
当我们尝试在组件内部使用useNavigate进行路由跳转时,发现数据保护失效了。以下是错误的实现方式:
function ProtectedRoute() {
const navigate = useNavigate();
useEffect(() => {
// 检查用户是否已登录
if (!isAuthenticated()) {
navigate('/login'); // 这里会跳转到登录页
}
}, []);
return <Outlet />;
}
正确解决方案
正确的做法是将保护逻辑提升到路由层级:
function App() {
return (
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/dashboard"
element={
isAuthenticated() ? <Dashboard /> : <Navigate to="/login" />
}
/>
</Routes>
);
}
注意事项
useNavigate在组件渲染时调用可能会导致循环跳转- 使用
<Navigate>组件替代直接的路由跳转 - 确保保护逻辑在组件挂载前执行
升级过程中遇到的另一个问题是,当使用<Outlet />时,如果父路由没有正确配置,会导致子路由数据丢失。建议在升级前做好充分测试。

讨论