我必须在React js上的浏览器返回事件上显示警报。我已经尝试使用addEventListener,但我不确定将代码放置在React页面中的何处。我应该放置在任何生命周期钩子中还是渲染中?我不确定。请帮助我。
addEventListener
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); }; }, []);
h9vpoimq2#
你可以试试这个
window.addEventListener('popstate', (event) => { alert("You message"); });
您可以根据需要将其放置在componentWillMount()或componentDidMount()中。Ref
componentWillMount()
componentDidMount()
nukf8bse3#
最后,我自己解决了。我已经用下面的代码给出了解释:首先,在componentDidUpdate或componentWillMount钩子中添加以下代码:
componentDidUpdate
componentWillMount
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方法上方添加以下代码:
pushState
window.addEventListener('popstate', (event) => { if (event.state) { //do your code here } }, false);
现在,当单击浏览器返回按钮时,上面的even listener将被调用,由于我们更新了state which pushState方法,if将为true,您可以在其中做任何您想做的事情。
state
if
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(); } } }); });
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; }
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
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); }; }, []);
htrmnn0y8#
更新的答案:
使用React路由器dom版本4和5(我个人测试了版本5,它工作得很好),你有一个非常简单的方法来做到这一点。只需从react-router-dom导入Prompt,你就可以有条件地显示浏览器警报和自定义消息:而不是when={true}。您可以随意将true替换为布尔类型的state,以启用或禁用此功能。
when={true}
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;
8条答案
按热度按时间enyaitl31#
如果您使用React钩子,您可以在以下步骤中使用useEffect钩子来完成它
h9vpoimq2#
你可以试试这个
您可以根据需要将其放置在
componentWillMount()
或componentDidMount()
中。Ref
nukf8bse3#
最后,我自己解决了。我已经用下面的代码给出了解释:
首先,在
componentDidUpdate
或componentWillMount
钩子中添加以下代码:我推送两次的原因是状态只有推送两次才会更新。下面是Ref。上面的代码将推送页面加载历史中当前页面的URL。
因此,当单击后退浏览器按钮时,由于历史记录已由
pushState
方法操作,因此将再次重新加载相同的页面。然后在
pushState
方法上方添加以下代码:现在,当单击浏览器返回按钮时,上面的even listener将被调用,由于我们更新了
state
whichpushState
方法,if
将为true,您可以在其中做任何您想做的事情。u7up0aaq4#
查看此链接How to Detect Browser Back Button event - Cross Browser
这里的关键点:
这可以防止后退空间被用于向后导航
d7v8vwbk5#
我已经尝试了这么多的解决方案,但没有一个工作在我的情况下,我发现这一点后
5lhxktic6#
我找到了这个解决方案,它对我来说很好。
Ref
vd2z7a6w7#
我在使用ref helped访问事件侦听器中的状态时遇到了问题。
htrmnn0y8#
更新的答案:
使用React路由器dom版本4和5(我个人测试了版本5,它工作得很好),你有一个非常简单的方法来做到这一点。只需从react-router-dom导入Prompt,你就可以有条件地显示浏览器警报和自定义消息:
而不是
when={true}
。您可以随意将true替换为布尔类型的state,以启用或禁用此功能。