React路由exact属性下history.push跳转异常:ACTION变为REPLACE并跳首页
以下代码中,updateData函数在PUT请求成功后调用history.push("/p/someroute/"),但实际跳转到了首页,且console.log(history)显示action为"REPLACE"而非预期的"PUSH":
export const updateData = (data, history) => (dispatch, getState) => { const promise = putRequest(`${url}`, data, dispatch, getState) .then(() => { history.push("/p/someroute/") }) .catch((error) => { setError(error, dispatch); }); return promise; };
路由配置如下,目标路径使用了exact属性的PrivateRoute:
<PrivateRoute exact path="/p/someroute/" component={SomeComponent} role={USER_ROLES.get("ADMIN")} />
调试发现,history.push执行前action为"PUSH",执行后立即变为"REPLACE"并跳转到首页,请问该异常的原因是什么?
PrivateRoute权限校验失败触发重定向:
目标路径是带exact的私有路由,history.push触发跳转后,PrivateRoute会校验当前用户角色是否匹配配置的ADMIN权限。如果用户实际角色不符合,PrivateRoute内部通常会执行history.replace跳转到首页(未授权默认逻辑),直接覆盖了之前的PUSH操作,导致最终action显示为REPLACE。
解决:验证当前用户角色确实是USER_ROLES.get("ADMIN"),或者排查PrivateRoute内部的权限校验逻辑是否存在错误。路径末尾斜杠与exact属性的匹配冲突:
跳转路径"/p/someroute/"末尾带斜杠,而PrivateRoute的path同样带斜杠且设置了exact。部分路由版本中,exact匹配会严格区分末尾斜杠,或者浏览器会自动规范化地址去掉斜杠,导致路由匹配失败,触发默认首页跳转(可能默认路由使用了replace)。
解决:统一路径格式,要么同时去掉末尾斜杠(改为"/p/someroute"),要么移除exact属性(确保该路径没有子路由冲突的前提下)。全局逻辑或putRequest内部干扰history:
检查putRequest函数内部是否存在修改history的逻辑,或者全局是否有路由监听、Redux中间件等,在路由跳转后执行了history.replace操作。比如全局权限拦截器在路由变化时重新校验,发现异常就强制跳转到首页。
解决:排查putRequest的实现代码,以及全局路由相关的中间件、监听逻辑,定位是否有额外的replace操作。
内容的提问来源于stack exchange,提问作者Raj Kumar Kausik

