React Router v6路由跳转参数丢失问题排查与修复
在将项目从React Router v5升级到v6的过程中,我们遇到了一个常见但容易被忽视的问题:路由跳转时参数丢失。这个问题严重影响了用户体验,需要仔细排查和修复。
问题现象
在v5中,我们使用<Route>组件的component属性进行路由匹配,通过this.props.history.push()进行跳转。升级到v6后,发现通过useNavigate Hook跳转时,部分参数丢失。特别是当URL包含复杂参数或嵌套路由时,问题更加明显。
复现步骤
- 创建一个带有参数的路由组件:
// v5写法
<Route path="/user/:id" component={UserComponent} />
// v6写法
<Route path="/user/:id" element={<UserComponent />} />
- 在组件中使用navigate进行跳转:
const navigate = useNavigate();
const handleClick = () => {
// 问题出现的跳转方式
navigate(`/user/${userId}?tab=profile&filter=active`);
}
- 在目标组件中读取参数:
const { id } = useParams();
const location = useLocation();
console.log(location.search); // 可能为空或不完整
根本原因分析
v6的路由机制与v5有显著差异,主要体现在以下几点:
useNavigate返回的函数现在会自动处理URL编码useLocation对象的结构发生变化- 参数传递方式需要重新审视
解决方案
方案一:使用search参数对象
const navigate = useNavigate();
const handleClick = () => {
navigate(`/user/${userId}`, {
state: { tab: 'profile', filter: 'active' },
replace: false
});
}
方案二:显式处理search参数
const handleClick = () => {
const searchParams = new URLSearchParams({
tab: 'profile',
filter: 'active'
});
navigate(`/user/${userId}?${searchParams.toString()}`);
}
方案三:使用useSearchParams Hook
const [searchParams, setSearchParams] = useSearchParams();
const handleClick = () => {
setSearchParams({ tab: 'profile', filter: 'active' });
}
通过以上调整,我们成功解决了v6版本的路由参数丢失问题,确保了升级后的功能稳定性。

讨论