在将React Router从v5升级到v6后,我们遇到了一个令人困惑的路由跳转安全性问题。问题表现为:当用户通过useNavigate进行路由跳转时,页面会意外刷新,导致组件重新挂载,丢失了当前状态。
复现步骤:
- 在v6环境中使用
useNavigate进行路由跳转 - 跳转到同一组件的不同路径(如
/user/1到/user/2) - 观察到页面完全刷新,组件重新挂载
问题分析: 经过排查发现,这是由于v6中路由配置方式的改变导致的。在v5中,我们使用<Route>组件直接嵌套,而在v6中需要使用<Routes>包裹,并且useNavigate的行为也有所调整。具体来说,当路由路径参数变化时,如果未正确处理组件的key属性,React会认为这是两个不同的组件实例。
解决方案:
- 为动态路由组件添加key属性:
const User = () => {
const { id } = useParams();
return <div key={id}>User {id}</div>;
};
- 或者使用
useEffect监听路由变化并保持状态:
const User = () => {
const { id } = useParams();
const navigate = useNavigate();
useEffect(() => {
// 保存当前状态
const savedState = getCurrentState();
// 跳转逻辑
navigate(`/user/${newId}`);
// 恢复状态
restoreState(savedState);
}, [id]);
};
这个问题在升级过程中需要特别注意,尤其是在处理动态路由时。

讨论