写博客时因为是在浏览器操作,很可能按错某个快捷键,页面就被关掉了,这样辛苦写的内容也会丢失。
即使有了文章草稿功能,页面被关掉也难保会有少量内容丢失,操作也麻烦。所以如果能拦截提示一下,就友好很多了。
编辑文本时记录状态
const [isChanged, setIsChanged] = useState(false);
使用 isChanged 记录当前是否存在未保存的数据。修改时记录,保存后重置。
阻止浏览器关闭
通过浏览器的 API,阻止浏览器关闭。参见: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/beforeunload_event
使用 useEffect 对 isChanged 进行监听,按需对 beforeunload 事件进行绑定和解绑。
useEffect(() => {
const onBeforeunload = (event: BeforeUnloadEvent) => {
event.preventDefault();
event.returnValue = '';
};
if (isChanged) {
window.addEventListener('beforeunload', onBeforeunload);
} else {
window.removeEventListener('beforeunload', onBeforeunload);
}
return () => {
window.removeEventListener('beforeunload', onBeforeunload);
};
}, [isChanged]);
React Router Prompt 拦截路由退出
单页应用浏览器点击回退或前进按钮时,很有可能会触发路由的切换,这时仅通过浏览器 API 就防不住了,需要在路由层面来控制。
React Router 提供了一个 Prompt 组件,可以在路由切换时按需发出提示。
import { Prompt } from 'react-router-dom';
<Prompt when={isChanged} message="是否离开页面? 你所做的更改可能未保存。" />
配合 isChanged,改变值时,阻止页面退出。
总结
以上,通过浏览器的阻止页面关闭事件,配合 React Router Prompt,实现“刷新、关闭页面”和“浏览器回退按钮”双重拦截。