微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

beforeunload 仅适用于页面刷新,不适用于页面离开

如何解决beforeunload 仅适用于页面刷新,不适用于页面离开

我正在使用 react-admin 框架 (3.2) 并且我试图在用户beforeunload 视图导航时触发 Edit form 事件。假设我的路径名是 "Feed/123"。当 url 以任何方式更改时(用户导航离开编辑表单),beforeunload 应该触发。 到目前为止,我已经尝试过这段代码

const FeedEdit = props => {
    const alertUser = (e) =>
    {
        e.preventDefault();
        e.returnValue = '';
        console.log('fired'); //console.log is present on F5,not when leaving the page
    }

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

    return <>
        <PageTitle type="edit" {...props} />
        <Edit {...props}>
          {/* other components */}
        </Edit>
    </>
};

然而,这只会在刷新 url 时触发 beforeunload 事件。任何想法如何在离开表单时触发事件?

提前致谢

解决方法

是的,没错,因为当您离开页面时会触发卸载,但是当您替换 url 时,您仍然在具有不同内容的同一页面中...

你可以通过添加一个新的钩子来跟踪组件包装器中的位置变化来做到这一点:

  const location = useLocation();

  useEffect(() => {
    console.log('Location changed',location);
  },[location]);

注意:你有很多选项可以帮助你反应路由器,你也可以构建一个自定义钩子,可以在任何你想要的地方重用跟踪代码......(如果你喜欢为特定路由处理它组件)

==================

更新 1

import { useRef,useEffect } from 'react';

const useUnload = fn => {
  const cb = useRef(fn); // init with fn,so that type checkers won't assume that current might be undefined

  useEffect(() => {
    cb.current = fn;
  },[fn]);

  useEffect(() => {
    const onUnload = cb.current;

    window.addEventListener("beforeunload",onUnload);
    window.addEventListener("unload",onUnload);

    return () => {
      window.removeEventListener("beforeunload",onUnload);
      window.removeEventListener("unload",onUnload);
    }
  },[]);
};

export default useUnload;

这是一个用于处理卸载页面的自定义钩子,我们可以通过在需要的组件中调用它来使用它,如下所示:

  // When Un-load event is trigger then trigger dis-counect and remove local track
  const unload = useCallback(() => {
....
  },[]);

  // Add event lisiner to trigger before unload
  useUnload(unload);

==================

更新 2

对于历史监听器,您可以使用 history.listen,例如:

  useEffect(() => {
    history.listen((loc,action) => {
      if(action === "POP"){// POP or PUSH
        window.location.reload();
      }
    });
  },[]);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。