使用 React 的浏览器后退按钮

IT技术 reactjs
2021-03-31 05:21:21

我正在使用react。当用户单击后退按钮时,我想警告用户。

我所做的是

handleWindowClose = (ev) => {
    ev.preventDefault();
    return ev.returnValue = 'Leaving this page will loose data';
}

componentDidMount = () => {
    window.addEventListener('beforeunload',this.handleWindowClose);
}

componentWillUnmount = () => {
    window.removeEventListener('beforeunload',this.handleWindowClose);
}

但是,这不适用于单击后退按钮。所以我尝试这样做:

handleWindowClose = (ev) => {
    ev.preventDefault();
    return ev.returnValue = 'Leaving this page will loose data';
}

onBackButtonEvent = (e) => {
    e.preventDefault();
    if (confirm("Do you want to loose this data")) {
        window.history.go(0);
    }
    else {
        window.history.forward();
    }
}

componentDidMount = () => {
    window.addEventListener('beforeunload',this.handleWindowClose);
    window.addEventListener('popstate',this.onBackButtonEvent);
}

componentWillUnmount = () => {
    window.removeEventListener('beforeunload',this.handleWindowClose);
    window.removeEventListener('popstate',this.onBackButtonEvent);
}

我没有使用react-router。有没有更好的方法只使用 React 来做到这一点?另外我希望窗口停留在该页面上而不使用 history.forward() 因为我会丢失窗口状态。

4个回答

在 React 中处理后退按钮时,我遇到以下问题:

  1. 第一次没有调用第一个popstate事件
  2. 它在执行我的后退按钮自定义逻辑后被调用两次

为了解决问题1,我做了以下代码:

componentDidMount() {
    window.history.pushState(null, null, window.location.pathname);
    window.addEventListener('popstate', this.onBackButtonEvent);
}

为了解决问题 2,我做了以下代码:

onBackButtonEvent = (e) => {
    e.preventDefault();

    if (!this.isBackButtonClicked) {
        if (window.confirm("Do you want to save your changes")) {
            this.isBackButtonClicked = true;
            // Your custom logic to page transition, like react-router-dom history.push()
        }
        else {
            window.history.pushState(null, null, window.location.pathname);
            this.isBackButtonClicked = false;
        }
    }
}

不要忘记添加this.isBackButtonClicked = false; 在构造函数中并取消取消事件。

componentWillUnmount = () => {
    window.removeEventListener('popstate', this.onBackButtonEvent);
}

我有一个类似的问题,并通过这种方式修复:

componentDidUpdate(){
  
    window.onpopstate  = (e) => {
        // Tour code...
    }      
}
此外,您可以在此处找到浏览器支持详细信息和简单示例
2021-05-25 05:21:21

试试这个代码:

componentDidMount() {
    window.addEventListener("popstate", this.onBackButtonEvent)
}

componentWillUnmount() {
  window.removeEventListener("popstate", this.onBackButtonEvent)
}

onBackButtonEvent = () => {
    window.history.forward()
}

看起来onbeforeunload就是你想要的:检查这个相关问题,其中包含一个有用的演示

此外,MDN 文档包含一个有用的示例。


假设你有一些不想使用的充分理由react-router,我将勾勒出 JavaScript 的方式来做到这一点

看起来您正在捕获错误的事件。您想获取 URL 哈希的任何更改,因此您应该使用onhashchange.

文档中的示例:

if ("onhashchange" in window) {
    alert("The browser supports the hashchange event!");
}

function locationHashChanged() {
    if (location.hash === "#somecoolfeature") {
        somecoolfeature();
    }
}

window.onhashchange = locationHashChanged;

但是,react-router鉴于您正在 React 中开发,我会试一试。在这种情况下,browserHistory将是你的朋友。

我没看到你提到的地方onbeforeunload你用beforeunload哪个不一样。而且,你错了:点击后退按钮onbeforeunload 触发。你真的检查过我在编辑中链接的演示吗?@dhrDatt
2021-05-24 05:21:21
似乎对我没有帮助。正如我之前提到的,我已经使用了这个事件。这不会在后退按钮上触发。它仅在刷新和窗口关闭事件时触发。
2021-05-27 05:21:21
使用 react-router..??这也不能成为现在的选项,因为应用程序已经构建
2021-06-11 05:21:21
我不是路由。我有一个向导类的应用程序。用户点击下一步,我使用 ajax 获取下一个数据。所以这没有在浏览器历史记录中注册。但是当用户点击后退按钮时,应用程序然后将他带出这个向导。所以我不能使用 hashChange 所以我没有留下窗口状态。有一些优雅的方法可以做到这一点,例如浏览器关闭事件。
2021-06-15 05:21:21
我用过这个 window.addEventListener('onbeforeunload',this.handleWindowClose); handleWindowClose = (ev) => { ev.preventDefault(); return ev.returnValue = 'Leaving this page will loose data'; }
2021-06-21 05:21:21