React 实现编辑页面异常退出自动拦截的功能

写博客时因为是在浏览器操作,很可能按错某个快捷键,页面就被关掉了,这样辛苦写的内容也会丢失。

即使有了文章草稿功能,页面被关掉也难保会有少量内容丢失,操作也麻烦。所以如果能拦截提示一下,就友好很多了。

编辑文本时记录状态

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,实现“刷新、关闭页面”和“浏览器回退按钮”双重拦截。

本文收录于专栏
一些博客建设的记录