添加但未删除 reactjs 事件侦听器 beforeunload
reactjs event listener beforeunload added but not removed
我有一个像这样的反应组件:
import React, { PropTypes, Component } from 'react'
class MyComponent extends Component {
componentDidMount() {
window.addEventListener("beforeunload", function (event) {
console.log("hellooww")
event.returnValue = "Hellooww"
})
}
componentWillUnmount() {
window.removeEventListener("beforeunload", function (event) {
console.log("hellooww")
event.returnValue = "Hellooww"
})
}
render() {
return (
<div>
Some content
</div>
)
}
}
export default MyComponent
这里事件列表器被添加到组件中。当我刷新页面时,它会弹出要求离开页面。
但是当我转到另一个页面并再次刷新它时显示相同的弹出窗口。
我正在从 componentWillUnmount
上的组件中删除 eventListener
。那为什么不删除呢?
如何删除其他页面上的 beforeunload
事件?
removeEventListener
应该获得对在 addEventListener
中分配的同一回调的引用。重新创建函数是行不通的。解决方案是在别处创建回调(本例中为 onUnload
),并将其作为对 addEventListener
和 removeEventListener
:
的引用传递
import React, { PropTypes, Component } from 'react';
class MyComponent extends Component {
onUnload = e => { // the method that will be used for both add and remove event
e.preventDefault();
e.returnValue = '';
}
componentDidMount() {
window.addEventListener("beforeunload", this.onUnload);
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.onUnload);
}
render() {
return (
<div>
Some content
</div>
);
}
}
export default MyComponent
反应挂钩
您可以使用 useRef
和 useEffect
挂钩将 beforeunload
事件处理抽象为自定义挂钩。
自定义钩子 useUnload
接收一个函数 (fn
) 并将其分配给当前 ref。它调用 useEffect
一次(在组件挂载时),并将事件处理程序设置为一个匿名函数,该函数将调用 cb.current
(如果它是 defined),并且 returns 进行清理删除事件处理程序的函数,当组件被删除时。
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 = (...args) => cb.current?.(...args);
window.addEventListener("beforeunload", onUnload);
return () => window.removeEventListener("beforeunload", onUnload);
}, []);
};
export default useUnload;
用法:
const MyComponent = () => {
useUnload(e => {
e.preventDefault();
e.returnValue = '';
});
return (
<div>
Some content
</div>
);
};
Ori 的解决方案对我不起作用。我必须这样做才能让它发挥作用...(感谢文档)
componentDidMount() {
window.addEventListener('beforeunload', this.handleLeavePage);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.handleLeavePage);
}
handleLeavePage(e) {
const confirmationMessage = 'Some message';
e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
return confirmationMessage; // Gecko, WebKit, Chrome <34
}
您可以使用以下钩子:
https://www.npmjs.com/package/react-beforeunload
示例:
import { Beforeunload } from 'react-beforeunload';
// ...
<Beforeunload onBeforeunload={(event) => event.preventDefault()}>
<MyApp />
</Beforeunload>
我有一个像这样的反应组件:
import React, { PropTypes, Component } from 'react'
class MyComponent extends Component {
componentDidMount() {
window.addEventListener("beforeunload", function (event) {
console.log("hellooww")
event.returnValue = "Hellooww"
})
}
componentWillUnmount() {
window.removeEventListener("beforeunload", function (event) {
console.log("hellooww")
event.returnValue = "Hellooww"
})
}
render() {
return (
<div>
Some content
</div>
)
}
}
export default MyComponent
这里事件列表器被添加到组件中。当我刷新页面时,它会弹出要求离开页面。
但是当我转到另一个页面并再次刷新它时显示相同的弹出窗口。
我正在从 componentWillUnmount
上的组件中删除 eventListener
。那为什么不删除呢?
如何删除其他页面上的 beforeunload
事件?
removeEventListener
应该获得对在 addEventListener
中分配的同一回调的引用。重新创建函数是行不通的。解决方案是在别处创建回调(本例中为 onUnload
),并将其作为对 addEventListener
和 removeEventListener
:
import React, { PropTypes, Component } from 'react';
class MyComponent extends Component {
onUnload = e => { // the method that will be used for both add and remove event
e.preventDefault();
e.returnValue = '';
}
componentDidMount() {
window.addEventListener("beforeunload", this.onUnload);
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.onUnload);
}
render() {
return (
<div>
Some content
</div>
);
}
}
export default MyComponent
反应挂钩
您可以使用 useRef
和 useEffect
挂钩将 beforeunload
事件处理抽象为自定义挂钩。
自定义钩子 useUnload
接收一个函数 (fn
) 并将其分配给当前 ref。它调用 useEffect
一次(在组件挂载时),并将事件处理程序设置为一个匿名函数,该函数将调用 cb.current
(如果它是 defined),并且 returns 进行清理删除事件处理程序的函数,当组件被删除时。
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 = (...args) => cb.current?.(...args);
window.addEventListener("beforeunload", onUnload);
return () => window.removeEventListener("beforeunload", onUnload);
}, []);
};
export default useUnload;
用法:
const MyComponent = () => {
useUnload(e => {
e.preventDefault();
e.returnValue = '';
});
return (
<div>
Some content
</div>
);
};
Ori 的解决方案对我不起作用。我必须这样做才能让它发挥作用...(感谢文档)
componentDidMount() {
window.addEventListener('beforeunload', this.handleLeavePage);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.handleLeavePage);
}
handleLeavePage(e) {
const confirmationMessage = 'Some message';
e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
return confirmationMessage; // Gecko, WebKit, Chrome <34
}
您可以使用以下钩子:
https://www.npmjs.com/package/react-beforeunload
示例:
import { Beforeunload } from 'react-beforeunload';
// ...
<Beforeunload onBeforeunload={(event) => event.preventDefault()}>
<MyApp />
</Beforeunload>