从链接进入,是因为新页面在新标签页打开的。
有子组件是因为公共组件提取
同样的操作,有一些简单的二级路由页面,就不会挂载两次。
关于定位这个问题,这次吃了个大亏,说一下思路和过程吧。
第一症状是这样的,链接进入二级路由,会发出两个相同的网络请求,这个请求是放在 componentDidMount 生命周期里的,如你所知,这个生命周期是用来做初始化操作的。
在组件的生命周期里 只会被调用一次。那么,两次请求的意思很明显,挂载了两次,到这里是很自然而然的考虑。so,在 componentWillUnmount生命周期里alert进行验证,猜想是需要验证才能确定的
。
确定了两次挂载后,就要考虑,哪些因素会让这个组件销毁一次?(找到销毁的原因等同于找到了挂两次的原因)
【三元判断】 在react世界里,没有类似vue中 keep-alive这种保存组件状态的东西, 我管它叫做 离开即销毁
。在开发中会经常用三元运算,来做显示不显示(这里没有隐藏,只有销毁)。
so,我首先想到的也是这个可能,(至少检查过之后,可以排除这个问题)。我进行了长时间的检查(从二级路由的路由组件,到父组件,到layout布局组件,甚至祖先级的兄弟组件 都进行了检查,这个工作量有点大了,这是需要注意的地方,以后在排查问题的过程中,应该首先保证有限的因素先排查,最后才大海捞针,节省时间
),结果跟你想的一样,毫无所获。那么这个三元判断的因素先排除。
【路由跳转?配置?】排除了上一个,再要想到的就是路由跳转和配置方面的问题。这里的路由还是老式的 对象配置方法(对象平铺,并不能嵌套),所以把路由捋了一遍,也没有发现什么问题。那么考虑会不会是配置出了问题呢?于是我又配置了一个测试路由,,配置顺序?匹配顺序?发现也有同样的问题,搞的我一下子不知所措了。彻底懵了。再仔细想想,还有什么能影响这个呢?我想了很久,还是没有头绪。难顶。。。
【安装devtools开发工具调试】 平常开发过程中,我一般是不用这个工具的,用不着,今天装上用它调试了一下,检查里 也没有发现什么问题,请求两次 ,state和props也没有异常。
<Switch>
{getRoutes(match.path, getRouters(routerData,match)).map(item => (
<Route
key={item.key}
path={item.path}
component={item.component}
exact={item.exact}
/>
))}
<Redirect to='/user/index/ioc' />
</Switch>
在思考路由的过程中,我还对每一级的路由进行了过滤,
const { routerData, match } = this.props;
const getRouters = (routerData,match) =>{
const routes = {}
Object.keys(routerData).map(route => {
if(route.indexOf(match.path)>-1){
return routes[route] = routerData[route];
}
})
return routes
}
在这个过程中,也感受到这种平铺对象操作的繁琐。但是到目前为止,关于这个bug的原因,没有一点进展,没有定位到问题所在,也没有解决方案。
【柳暗花明】事情的转机出现在我6点下楼抽了一颗烟,空气中分不清是雾还是霾,我觉得 实在找不到原因,就重写一下页面,或者对项目进行一个大重构。回来之后,我把这个组件挂到主页路由上,这时候奇迹出现了,不会挂载2次了,我那个兴奋啊 , 从业以来花时间最长的bug,终于可以让我喘口气,我把这个页面放在一级路由,发现是完美运行的。 到这里,业务上的问题可以解决,但是还是没有把问题搞清楚。
于是,我考虑二级路由的问题,我至今还是没想明白为什么二级路由,别的页面不会挂载2次,仅这两个页面挂载2次,隐约觉得,这两个页面也是有问题的。
【其他尝试】发现二级路由的问题之后,由于并不想把它俩放在顶层路由,我干脆给它放到三级路由了,原始页面仍然有问题,换空白组件测试,通过了。然后一下一下的还原,发现只要引入了一个table的公共组件,就会挂载2次。
【最后】最后又尝试二级路由,不显示table组件,这种情况下,发现也是正常的,所以基本排除路由的问题了。
在react世界里,到处都充满了蝴蝶效应,有时候你的一个巨大bug,很可能就是一个逗号引起的,所以搞react开发的同学,要更认真仔细了
。原文:https://www.cnblogs.com/chengyunshen/p/11415643.html