react-router ^5.2.0点击跳转新路由后仍保留旧路由prop值的问题
问题原因
这个问题是React Router v5路由组件复用的典型现象:当两次跳转的路径匹配同一个Route规则、仅路径参数变化时,React Router默认不会重新挂载对应组件,只会更新传入的路由props。如果你的CompanyDetailContainer仅在组件挂载阶段(class组件componentDidMount、函数组件空依赖的useEffect)读取companyId,就只会拿到第一次挂载时的旧值,后续参数更新不会重新触发逻辑,就会出现URL已更新但参数还是旧值的问题。
解决方案
方案1:强制路由参数变化时重新挂载组件(改动最小)
渲染CompanyDetailContainer时绑定key为当前的companyId,参数变化时React会直接销毁旧组件挂载新组件,直接拿到最新参数:
<Switch> <Route path="/companies/:companyId/details" render={(props: RouteComponentProps<{ companyId: string }>) => ( <CompanyDetailContainer {...props} // pass routing props key={props.match.params.companyId} // 新增该行,绑定companyId为key fetchCompanyNew={fetchCompanyNew} findOne={findOne} httpRequest={Request} useFetchDataCompany={useFetchDataCompany} /> )} /> <Route component={withTracker(Container)} path="/" /> <Route component={withTracker(NotFound)} path="*" /> </Switch>
方案2:监听路由参数变化时重新执行业务逻辑(性能更优)
如果销毁重挂载会影响你的业务逻辑、需要保留组件内部其他状态,可以修改CompanyDetailContainer内部逻辑,监听参数变化:
函数组件写法
把companyId加入useEffect依赖数组:
useEffect(() => { const currentCompanyId = props.match.params.companyId // 此处编写获取企业详情的相关逻辑 fetchCompanyNew(currentCompanyId) }, [props.match.params.companyId])
Class组件写法
在componentDidUpdate生命周期里判断参数变化:
componentDidUpdate(prevProps) { if (prevProps.match.params.companyId !== this.props.match.params.companyId) { const currentCompanyId = this.props.match.params.companyId // 执行获取企业详情的相关逻辑 } }
额外排查点
如果上述方案未生效,检查以下三点:
- 是否给
CompanyDetailContainer加了React.memo,如果有则需要把路由相关props加入比较逻辑,避免props更新被缓存拦截 - 检查
withTracker高阶组件是否完整透传了路由相关的props,确保路由参数更新时会同步到组件内部 - 你的
Link跳转的uri定义中,companies/${company.id}/details开头没有加斜杠,属于相对路径,如果你当前页面不在根路径下可能出现路径拼接错误,建议统一修改为绝对路径:/companies/${company.id}/details
内容的提问来源于stack exchange,提问作者PositiveGuy
相关产品推荐
相关产品推荐

