componentWillUnmount路由跳转优先级低于浏览器回退,如何阻止跳回A组件
问题根因
你当前的实现存在时序逻辑问题:
浏览器点击回退按钮时,会优先触发历史记录切换,路由先回退到/form路径触发A组件挂载(因此你会看到componentDidMount的打印日志),之后B组件才会触发卸载执行componentWillUnmount中的跳转逻辑,所以无法避免A组件的渲染。
解决方案
方案1(最优,无额外逻辑)
直接修改A组件提交成功后的跳转方法,将history.push替换为history.replace即可:
onSubmit () { // on success of api this.props.history.replace({ pathname: '/success', search: '?viewType=success' }) }
原理说明:
history.push会在浏览器历史栈新增一条/success记录,此时历史栈为[...上级页面记录, /form, /success],回退自然回到/form路径history.replace会把当前栈顶的/form记录替换为/success,历史栈变为[...上级页面记录, /success],点击回退会直接回到/form之前的上级页面,全程不会触发A组件渲染,也不需要在B组件编写额外的卸载跳转逻辑
方案2(特殊场景使用,需保留/form历史记录)
如果你有其他业务场景必须保留/form的历史记录,不能修改跳转方式,可以在B组件中提前拦截回退动作,避免路由先切换到/form:
首先删除B组件componentWillUnmount中的原有跳转逻辑,新增监听逻辑如下:
componentDidMount() { // 监听浏览器回退事件 window.addEventListener('popstate', this.handleBack) } componentWillUnmount() { // 卸载时移除监听,避免影响其他页面逻辑 window.removeEventListener('popstate', this.handleBack) } handleBack = () => { const viewType = new URLSearchParams(this.props.location?.search)?.get('viewType'); if(viewType === 'success'){ this.props.history.replace('/home') } else { this.props.history.replace('/') } }
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

