我试图在离开页面之前提示用户。我注意到当用户从元素链接进入页面时,当我点击返回时,beforeunload事件触发。
但是,当用户通过NextJs Link组件进入页面时,点击返回不会触发beforeunload事件。
如何在使用组件时仍然提示用户?
例如,从这个链接跳转到另一个页面并点击返回不会触发beforeunload<Link href={`/event/${encodeURIComponent(event.slug)}`}>
<a>
<h3>{event.name}</h3>
</a>
</Link>
但是常规的元素链接之后会在点击返回
时触发beforeunload
例子<a href={"event/" + event.slug}>
<h3>{event.name}</h3>
</a>
根据Next.js文档,当您使用Link
组件时:
路由之间的客户端转换可以通过next/Link导出的Link组件启用。Next.js路由器允许你在页面之间进行客户端路由转换,类似于单页应用。
您正在使用Link
组件更改您的路由,因此它被认为您在单页(甚至来回走了很多次)。
现在,看看MDN上的Window: beforeunload event
:
当窗口、文档及其资源即将被卸载时触发beforeunload事件。此时,文档仍然可见,事件仍然可以取消。
因此,当您使用上述特定的Link
组件时,它不是正确的行为。
作为解决问题的解决方案,您可以添加useEffect
钩子并对其或cleanup
方法执行适当的操作。例如,将函数放在所需页面的useEffect
中,以便在组件挂载时调用。这样,每次路由或页面发生变化,useEffect
都会被触发。
更新后的解决方案2023
这是pages目录的解决方案(未在app上测试!)当你在Next.js
中切换页面或离开页面时,它会检测到工作原理:
- 使用路由器更改事件-跟踪何时更改页面而不刷新
- 使用窗口。onbeforeunload事件-跟踪用户何时关闭选项卡或刷新页面 代码:
请在_app.js文件中使用这段代码。你也可以把它放在一个特定的页面,但它不会在所有的页面上执行。你也可以为它创建一个单独的文件,并在需要的地方导入它。
useEffect(() => {
const exitingFunction = async () => {
console.log("exiting...");
};
router.events.on("routeChangeStart", exitingFunction);
window.onbeforeunload = exitingFunction;
return () => {
console.log("unmounting component...");
router.events.off("routeChangeStart", exitingFunction);
};
}, []);