我试图在反应上使用 beforeUnload 事件在选项卡关闭或用户刷新页面之前执行操作,该事件永远不会触发...我正在应用程序组件上使用效果。
import "./styles/global.css";
import Home from "./sections/Home";
import Header from "./components/Header";
import Footer from "./components/Footer";
import { useEffect } from "react";
function App() {
useEffect(() => {
const onBeforeUnload = (ev) => {
ev.returnValue = "Anything you wanna put here!";
return "Anything here as well, doesn't matter!";
};
window.addEventListener("beforeunload", onBeforeUnload);
return () => {
window.removeEventListener("beforeunload", onBeforeUnload);
};
}, []);
return (
<div className="App">
<Header />
<Home />
<Footer />
</div>
);
}
export default App;
import "./styles/global.css";
import Home from "./sections/Home";
import Header from "./components/Header";
import Footer from "./components/Footer";
import { useEffect } from "react";
function App() {
useEffect(() => {
const onBeforeUnload = (ev) => {
//#############
console.log("SOME CODE HERE");
//#############
ev.returnValue = "Anything you wanna put here!";
return "Anything here as well, doesn't matter!";
};
window.addEventListener("beforeunload", onBeforeUnload);
return () => {
window.removeEventListener("beforeunload", onBeforeUnload);
};
}, []);
return (
<div className="App">
<Header />
<Home />
<Footer />
</div>
);
}
export default App;
使
useEffect
在任何更新时触发(通过删除空依赖项),
然后在关闭选项卡或刷新之前放入您希望执行的任何代码。
useEffect(() => {
window.addEventListener("beforeunload", () => {
// any code you want
});
});
您缺少的神奇成分是
preventDefault
。正如 Mozilla 解释:
窗口:卸载事件之前
当当前窗口、包含的文档和关联资源即将被卸载时,会触发 beforeunload 事件。此时文档仍然可见,并且活动仍然可以取消。
此事件的主要用例是触发浏览器生成的确认对话框,要求用户在尝试关闭或重新加载页面或导航到其他位置时确认是否确实要离开页面。这是为了帮助防止丢失未保存的数据。
可以通过以下方式触发该对话框:
- 调用事件对象的preventDefault()方法。
- 将事件对象的 returnValue 属性设置为非空字符串值或任何其他真值。
- 从事件处理函数返回任何真值,例如返回“字符串”。请注意,这仅在通过 onbeforeunload 属性(而不是 addEventListener() 方法)附加函数时才有效。此行为在现代版本的 Firefox、Safari 和 Chrome 中是一致的。
最后两个机制是遗留功能;最佳实践是通过在事件对象上调用 PreventDefault() 来触发对话框,同时设置 returnValue 以支持旧情况。
假设你有一个布尔变量
isDirty
- 一个布尔值。当表单“脏”(有未保存的内容)时,变量为 true
,否则为 false
。因此,您可以编写一个 useEffect
,如果用户在表单有未保存的内容时尝试关闭窗口,则向用户显示一个对话框。
useEffect(() => {
const onBeforeUnload = (ev: Event) => {
if (isDirty) {
ev.preventDefault();
}
ev.returnValue = isDirty;
return isDirty;
};
window.addEventListener('beforeunload', onBeforeUnload);
return () => {
window.removeEventListener('beforeunload', onBeforeUnload);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
注意:
returnValue
属性已弃用,因此在启用 ESLint 的 VSCode 中,您可能会看到一个下划线。
我已经让它工作了,谢谢!!...显然,我在重新加载页面时没有弹出窗口(这是一件神秘的事情),但返回之前的代码执行得很好。