Angular v5 + @ngrx/router-store导航ID不匹配问题求助
我之前也碰到过类似的Navigation ID X is not equal to the current navigation id Y问题,结合你给出的排查细节,给你几个可以深挖的方向:
检查路由B/A关联的守卫/解析器
虽然你说路由B没特殊逻辑,但有可能在跳转过程中,某个路由守卫(CanActivate/CanDeactivate等)或解析器(Resolve)里的异步操作搞乱了导航时序。比如守卫里调用了API,回调中触发了额外的路由跳转,或者间接触发了ngrx action导致导航竞态。重点排查这些逻辑里有没有router.navigate调用,或者Observable回调中涉及路由的操作。排查ngrx Effects中的导航竞态
你提到跳转时没看到其他导航操作,但有可能某个监听路由B相关action的Effect,在处理过程中发起了导航请求,和你手动触发的跳转形成了竞态。比如从B跳转到A时,B组件触发的action对应的Effect里调用了router.navigate或@ngrx/router的Goaction,两个导航请求同时触发,导致router-store的ID同步混乱。可以在所有涉及导航的Effect里加日志,追踪跳转B→A时的action派发情况。确认版本兼容性
Angular v5对应的@ngrx/router-store应该是v5.x版本,如果你的项目里@ngrx包和@angular/router版本不匹配(比如不小心升级了更高版本的@ngrx),很可能出现路由状态同步的兼容性问题。检查package.json里@ngrx/router-store、@ngrx/store和@angular/router的大版本是否一致(均为v5)。检查路由配置的重定向/嵌套规则
看看路由A或B的配置里有没有不正确的重定向(redirectTo),或者嵌套路由的pathMatch设置错误。比如路由A的子路由有默认重定向,进入A时会触发两次导航,router-store可能无法正确处理这种内部跳转的ID同步。手动追踪router-store的状态更新
你可以自定义RouterStateSerializer,或者在路由reducer里添加日志,打印每次ROUTER_NAVIGATION、ROUTER_NAVIGATION_END、ROUTER_CANCEL动作的payload.navigationId,以及当前store状态中的navigationId,对比看看是不是某个环节ID被提前递增,或者没有被正确同步。
另外你提到非调试环境下ID总是差1、调试环境差值更大,这说明是异步操作的时序问题——调试断点会延迟代码执行,放大了竞态的时间差,导致ID差值更随机;生产环境下异步时序相对固定,所以总是差1。
内容的提问来源于stack exchange,提问作者John

