reactjs 在react js上的浏览器返回按钮事件上显示警报

oknwwptz  于 2023-04-20  发布在  React
关注(0)|答案(8)|浏览(185)

我必须在React js上的浏览器返回事件上显示警报。我已经尝试使用addEventListener,但我不确定将代码放置在React页面中的何处。我应该放置在任何生命周期钩子中还是渲染中?我不确定。请帮助我。

enyaitl3

enyaitl31#

如果您使用React钩子,您可以在以下步骤中使用useEffect钩子来完成它

import React, { useState, useEffect } from "react";

const [finishStatus, setfinishStatus] = useState(false);

const onBackButtonEvent = (e) => {
    e.preventDefault();
    if (!finishStatus) {
        if (window.confirm("Do you want to go back ?")) {
            setfinishStatus(true)
            // your logic
            props.history.push("/");
        } else {
            window.history.pushState(null, null, window.location.pathname);
            setfinishStatus(false)
        }
    }
}

  useEffect(() => {
    window.history.pushState(null, null, window.location.pathname);
    window.addEventListener('popstate', onBackButtonEvent);
    return () => {
      window.removeEventListener('popstate', onBackButtonEvent);  
    };
  }, []);
h9vpoimq

h9vpoimq2#

你可以试试这个

window.addEventListener('popstate', (event) => {
  alert("You message");
});

您可以根据需要将其放置在componentWillMount()componentDidMount()中。
Ref

nukf8bse

nukf8bse3#

最后,我自己解决了。我已经用下面的代码给出了解释:
首先,在componentDidUpdatecomponentWillMount钩子中添加以下代码:

window.history.pushState({name: "browserBack"}, "on browser back click", window.location.href);
window.history.pushState({name: "browserBack"}, "on browser back click", window.location.href);

我推送两次的原因是状态只有推送两次才会更新。下面是Ref。上面的代码将推送页面加载历史中当前页面的URL。
因此,当单击后退浏览器按钮时,由于历史记录已由pushState方法操作,因此将再次重新加载相同的页面。
然后在pushState方法上方添加以下代码:

window.addEventListener('popstate', (event) => {
  if (event.state) {
    //do your code here
  }
 }, false);

现在,当单击浏览器返回按钮时,上面的even listener将被调用,由于我们更新了state which pushState方法,if将为true,您可以在其中做任何您想做的事情。

u7up0aaq

u7up0aaq4#

查看此链接How to Detect Browser Back Button event - Cross Browser
这里的关键点:

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

这可以防止后退空间被用于向后导航

$(function(){
        /*
         * this swallows backspace keys on any non-input element.
         * stops backspace -> back
         */
        var rx = /INPUT|SELECT|TEXTAREA/i;

        $(document).bind("keydown keypress", function(e){
            if( e.which == 8 ){ // 8 == backspace
                if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                    e.preventDefault();
                }
            }
        });
    });
d7v8vwbk

d7v8vwbk5#

我已经尝试了这么多的解决方案,但没有一个工作在我的情况下,我发现这一点后

componentDidMount() {
        window.addEventListener("beforeunload", this._confirm);
        window.history.pushState(null, "", window.location.href);
        window.onpopstate = this._backConfirm;
    }

    componentWillUnmount() {
        window.removeEventListener("beforeunload", this._confirm);
        window.onpopstate = () => { }
    }

    _backConfirm = async () => {
        let event = window.confirm("Changes that you may not be saved.");
        if(event){
            window.history.pushState(null, "", window.location.href);
        }
    }

    _confirm = (e) => {
        var confirmationMessage = "\o/";
        e.returnValue = confirmationMessage;
        return confirmationMessage;
    }
5lhxktic

5lhxktic6#

我找到了这个解决方案,它对我来说很好。

constructor(props) {
    super(props);
    this.state = {
        onClickBackButton: false
    };
}
componentDidMount() {
   window.history.pushState(null, null, window.location.pathname);
   window.addEventListener('popstate', this.onClickBackButton);
}

onBackButtonEvent = (e) => {
    e.preventDefault();
    if (!this.onClickBackButton) {

        if (window.confirm("Do you want to go back without submitting details?")) {
            this.onClickBackButton= true;
            // your custom logic to page transition,like react-router-dom 
            history.push()
        } else {
            window.history.pushState(null, null, window.location.pathname);
            this.onClickBackButton= false;
        }
    }
}

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

Ref

vd2z7a6w

vd2z7a6w7#

我在使用ref helped访问事件侦听器中的状态时遇到了问题。

import React, { useState, useEffect } from "react";

const [finishStatus, _setfinishStatus] = useState(false);

const finishStatusRef = React.useRef(isUpdated);
const setfinishStatus = data => {
  finishStatusRef.current = data;
  _setfinishStatus(data);
};

const onBackButtonEvent = (e) => {
    e.preventDefault();
    if (!finishStatusRef.current) {
        if (window.confirm("Do you want to go back ?")) {
            setfinishStatus(true)
            // your logic
            props.history.push("/");
        } else {
            window.history.pushState(null, null, window.location.pathname);
            setfinishStatus(false)
        }
    }
}

  useEffect(() => {
    window.history.pushState(null, null, window.location.pathname);
    window.addEventListener('popstate', onBackButtonEvent);
    return () => {
      window.removeEventListener('popstate', onBackButtonEvent);  
    };
  }, []);
htrmnn0y

htrmnn0y8#

更新的答案:

使用React路由器dom版本4和5(我个人测试了版本5,它工作得很好),你有一个非常简单的方法来做到这一点。只需从react-router-dom导入Prompt,你就可以有条件地显示浏览器警报和自定义消息:
而不是when={true}。您可以随意将true替换为布尔类型的state,以启用或禁用此功能。

import { Prompt } from "react-router-dom";

const MyComponent = () => {
  return (
    <>
      <Prompt when={true} message="are you sure you want to leave this page?" />

      {/* REST OF YOUR CODE LOGIC */}
    </>
  );
};

export default MyComponent;

相关问题