事件监听器beforeunload在React中无效

5

我正试图使用以下代码在React中打开一个弹出窗口,当用户关闭一个标签页时:

useEffect(() => {
    
    window.addEventListener('beforeunload',handleUnload );
    return () => {
      window.removeEventListener('beforeunload', handleUnload);
    }
  }, []);
  

  const handleUnload = (e) => {
    e.preventDefault();
   console.log('hey')
   alert("HEY");
  }

还有其他方法可以完成这个任务吗?或者我是否可以修改代码来实现目标。目前我正在尝试警告用户。


为什么要在 handleUnload 中包裹 {}?移除它们,你应该只传递一个函数引用。代码应该是 window.addEventListener('beforeunload', handleUnload) - zero298
3个回答

1

尝试使用引用:

const useUnload = (fn) => {
  const cb = React.useRef(fn);

  React.useEffect(() => {
    const onUnload = cb.current;
    window.addEventListener('beforeunload', onUnload);
    return () => {
      window.removeEventListener('beforeunload', onUnload);
    };
  }, [cb]);
};

然后使用这个来调用。
useUnload((e) => {
  e.preventDefault();
  console.log('hey')
  alert("HEY");
});

2
为什么我必须使用它? - Baryarte
@Baryarte 因为在函数组件内部定义的所有不属于 hooks 流程的内容(普通变量、函数等)都会在组件重新渲染时重新定义。所以,当你尝试在组件卸载时移除监听器时,它已经是一个完全不同的函数副本,与你在首次添加事件监听器(在组件挂载时)时使用的函数不同。 - undefined

0
我知道这不是对OP提出的问题的确切答案,但在试图弄清楚如何仅在用户有未保存的更改时提示时,我偶然发现了这个。最终,我通过以下代码成功实现了该逻辑:
<pre>
    let [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false);

    const [unsavedChangesCallback, setUnsavedChangesCallback] = React.useState(() => (e) => {
        let message = "You have unsaved changes, are you sure you want to leave?";
        e.returnValue = message;
        return message;
    });

    useEffect(() => {
        if (hasUnsavedChanges) {
            window.addEventListener('beforeunload', unsavedChangesCallback);
        } else {
            window.removeEventListener('beforeunload', unsavedChangesCallback);
        }
    }, [hasUnsavedChanges, unsavedChangesCallback]);
</pre>

然后你所要做的就是根据你的应用程序当前是否有未保存的更改来更新hasUnsavedChanges的值,它将相应地进行提示。

0

欢迎来到SO!

我认为您无意中使用了{}破坏了您的函数。

尝试这个:

useEffect(() => {
  window.addEventListener("beforeunload", handleUnload);

  return () => window.removeEventListener("beforeunload", handleUnload);
}, [handleUnload]);

我已经将[handleUnload]添加到useEffect的第二个属性中,以防止在每次状态更改时添加和删除事件侦听器。

您会发现handleUnload事件正在触发,但并非所有当前浏览器都支持您的PreventDefault调用。请参阅此处链接:[link]https://developer.mozilla.org/zh-CN/docs/Web/API/Window/beforeunload_event - milano_jon
为什么没有显示警告? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接