React组件卸载生命周期、路由跳转和页面封闭三者看起来有些相似的处所,比方都是当前组件即将从视口消逝,但现实上所触发的事宜均不雷同。以一个现实案例动身:
某单页运用的
文章编辑页用户正在编辑文章,此时还没有保留。当用户不小心要跳转到别的一个路由时须要提醒用户是不是继承跳转,这个历程须要触发路由跳转以及组件卸载;
而用户不小心点了封闭标签页按钮,或革新了页面。这个历程触发了页面卸载事宜;
在这个案例中我们须要完成:
1. 用户跳转页面时弹出提醒框(路由采纳histroy形式)
2. 用户封闭页面时弹出提醒框
componentWillUnmount
起首这个钩子函数是在组件卸载前挪用的一个函数,它并不能阻挠当前组件的卸载。所以不要千方百计在这里做提醒,由于即使提醒了,组件照样会卸载,文章照样会消逝。
路由守御-<Prompt/>
为了完成第一个功用,须要一个跳转路由之前举行的推断。在react-router-dom 4.0
以后作废了先前的路由守御(实在我没研讨过之前版本的,这个形貌摘自收集)。在react-router-dom 4.0
以后,完成这个功用能够依托<Prompt/>
组件。文档链接↗
把这个组件增加到你的文章编辑页组件的恣意部份
import {Prompt} from 'react-router-dom';
const Editor=()=>{
return (
<div>
<Prompt
when={true}
message={location => '文章要保留吼,肯定脱离吗?'}
/>
</div>
)
}
这里有一点须要注重,运用<Prompt/>
时,你的路由跳转必需经由过程<Link/>
完成,而不能依托<a/>
原生标签。
点击作废时就会留在当前页面。至此已完成了路由跳转时提醒用户举行保留的功用。
窗口封闭事宜-beforeunload
完成第二个功用须要依托对窗口的监听。React运用中关于窗口事宜的运用远没有DOM事宜频仍,所以好久没遇到照样有点手生的。最症结的就是,应该在什么时候举行监听?
应该在组件挂载时监听事宜,组件卸载时移除事宜监听。由于我已最先周全采纳hooks
新特征了,所以这里运用到useEffect
。
import React,{useEffect} from 'react';
const Editor=()=>{
//监听窗口事宜
useEffect(() => {
const listener = ev => {
ev.preventDefault();
ev.returnValue='文章要保留吼,肯定脱离吗?';
};
window.addEventListener('beforeunload', listener);
return () => {
window.removeEventListener('beforeunload', listener)
}
}, []);
//return ...
}
这里有几个须要注重的处所:
-
useEffect
第二个参数为空数组,示意只挪用了componentDidMount
和componentWillUnmount
两个钩子 - 事宜监听和移除的第二个参数为同一个事宜处置惩罚函数
- 在
beforeunload
事宜中的confirm
,prompt
,alert
会被疏忽。取而代之的是一个浏览器内置的对话框。(参考:MDN|beforeunload) - 必需要有
returnValue
且为非空字符串,但是在某些浏览器中这个值并不会作为弹窗信息