开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
这天本来风和日丽,项目刚刚迭代了一个版本,新的迭代,也不着急。
产品小姐姐找到我说,线上又发现了一个小问题,就你比较闲,你看看能不能解决一下。她当然不是这么说的,同事说话还是很客气的,大概是这么个意思。
问题就是有些弹窗在浏览器前进后退时,不会自动销毁。 项目用的是react-antd-design.
路由变化时销毁弹窗
我定位了一下问题所在,那就是使用了Modal 的快捷apiModal.confirm
之类的,会出现这个问题。
咱们也不探究,这个问题是不是因为这个快捷方法直接把组件放到body里,以至于没有父组件带着一起消失。
直接来看文档,文档果然给出了解决办法。
我找到了项目路由的地方,说真的,我不会react。项目使用的是useHistory
,我试了一下,ts语法也承认它下面有个listen方法,但是没有触发。我又发现,旁边还有一个路由守卫,我就在那里写上了一行代码,解决了问题。 然而并没有完全解决。
我已经准备发布到测试服了,结果发现,还有一个弹窗没能关闭。 原来是二次封装的Modal组件,但是这里不存在什么继承,所以destoryAll
没能起作用。
我当然可以直接去在使用这个组件的地方,加上一个监听路由变化的销毁,但是,如果后面还有其他地方用到呢。 所以,我觉得还是应该模仿一下他的实现。
Modal.destroyAll的实现
正巧我要查源码的时候,git又不好使了,等到快下班的时候,突然又好了。
午休过后,我看了看源码的实现,比我想的要简单的多。
就是在Modal
函数外部声明一个数组, 在Modal
函数内部把销毁方法装进去,然后给Modal
函数增加一个destroyAll
方法。是的,函数也能有自己的属性方法,万物皆对象,就不啰嗦了。
index.tsx
Modal.destroyAll = function destroyAllFn() {
while (destroyFns.length) {
const close = destroyFns.pop();
if (close) {
close();
}
}
};
destroyFns.ts
const destroyFns: Array<() => void> = [];
export default destroyFns;
这样,我就照着写了一个,并且直接把存放销毁方法的数组就在那个封装的组件里声明了。
openModal.tsx
const destroyFncs: Array<(...args: any) => void> = [];
......
destroyFncs.push(destroy);
render(true);
.....
openModal.destoryAll = () => {
while (destroyFncs.length) {
const close = destroyFncs.pop();
if (close) {
close();
}
}
};
这下,问题就是完整解决了。等于是直接把源码复制过来了。
这就源码解决问题的一般态度,拿来就用。