事件侦听器的 React useEffect 清理
React useEffect cleanup for event listener
在我的 React 组件中,我有一个针对 beforeunload 的事件处理。我想在我的 useEffect return 中清理它。下面的代码是做同样事情的正确方法还是有更好的方法?
useEffect(() => {
if (Object.keys(someKey).length > 0) {
function callSvc(urls) {
}
callSvc(urls);
const intV = setInterval(callSvc, interval, urls);
window.addEventListener("beforeunload", function() {clearInterval(intV)});
return () => {
//window.removeEventListener("beforeunload", function() {clearInterval(intV)});
}
}
}, [someKey])
更新代码
useEffect(() => {
if (Object.keys(someKey).length > 0) {
const intV = setInterval(callSvc, interval, urls);
function clearTimer() {
clearInterval(intV)
}
window.addEventListener("beforeunload", clearTimer);
return () => {
window.removeEventListener("beforeunload", clearTimer);
}
}
}, [someKey])
这是 return
if-block 中函数的正确方法,useEffect()
只有在 if-statement 中的条件为 [=15= 时才会 clean-up ],但是当没有要添加的侦听器时,不需要在 useEffect()
函数的顶层 clean-up。
useEffect(()=>{
let getThere = someBoolean
if (getThere) {
console.log("Listener Added.")
return () => {
console.log("Listener Removed. (Inside If statement)")
}
}
return () => {
console.log("No Listener to Remove.")
}
},[])
然后通过mount/unmount测试切换页面(我目前使用的是react-router-dom
)然后观察控制台。
如果条件是 true
Listener Added.
Listener Removed. (Inside If statement)
如果条件是false
No Listener to Remove.
如果布尔值是 true
函数将 return 仅 if-block 内部的函数,不会流入外部 return,除了布尔值是 false
,代码将转到外层的return。
Is the below code the correct way of doing the same or is there any better way ?
您的代码存在一个关键问题:只有当您向 removeEventListener
传递与传递给 addEventListener
的函数完全相同时,才能删除事件处理程序。但就目前而言,您正在传递两个不同的功能。这很容易解决,只需将函数存储在变量中并在 addEventListener
和 removeEventListener
.
中引用该变量
但是,我怀疑 beforeunload
事件处理程序是否必要。当页面关闭时,任何 JS 代码都会停止 运行。我认为当效果 re-runs 时停止间隔更重要,否则每当效果再次运行时,您将开始一个新的间隔,从而导致多个并行间隔:
useEffect(() => {
if (Object.keys(someKey).length > 0) {
function callSvc(urls) {
}
callSvc(urls);
const intV = setInterval(callSvc, interval, urls);
return () => {
clearInterval(intV)
}
}
}, [someKey])
在我的 React 组件中,我有一个针对 beforeunload 的事件处理。我想在我的 useEffect return 中清理它。下面的代码是做同样事情的正确方法还是有更好的方法?
useEffect(() => {
if (Object.keys(someKey).length > 0) {
function callSvc(urls) {
}
callSvc(urls);
const intV = setInterval(callSvc, interval, urls);
window.addEventListener("beforeunload", function() {clearInterval(intV)});
return () => {
//window.removeEventListener("beforeunload", function() {clearInterval(intV)});
}
}
}, [someKey])
更新代码
useEffect(() => {
if (Object.keys(someKey).length > 0) {
const intV = setInterval(callSvc, interval, urls);
function clearTimer() {
clearInterval(intV)
}
window.addEventListener("beforeunload", clearTimer);
return () => {
window.removeEventListener("beforeunload", clearTimer);
}
}
}, [someKey])
这是 return
if-block 中函数的正确方法,useEffect()
只有在 if-statement 中的条件为 [=15= 时才会 clean-up ],但是当没有要添加的侦听器时,不需要在 useEffect()
函数的顶层 clean-up。
useEffect(()=>{
let getThere = someBoolean
if (getThere) {
console.log("Listener Added.")
return () => {
console.log("Listener Removed. (Inside If statement)")
}
}
return () => {
console.log("No Listener to Remove.")
}
},[])
然后通过mount/unmount测试切换页面(我目前使用的是react-router-dom
)然后观察控制台。
如果条件是 true
Listener Added.
Listener Removed. (Inside If statement)
如果条件是false
No Listener to Remove.
如果布尔值是 true
函数将 return 仅 if-block 内部的函数,不会流入外部 return,除了布尔值是 false
,代码将转到外层的return。
Is the below code the correct way of doing the same or is there any better way ?
您的代码存在一个关键问题:只有当您向 removeEventListener
传递与传递给 addEventListener
的函数完全相同时,才能删除事件处理程序。但就目前而言,您正在传递两个不同的功能。这很容易解决,只需将函数存储在变量中并在 addEventListener
和 removeEventListener
.
但是,我怀疑 beforeunload
事件处理程序是否必要。当页面关闭时,任何 JS 代码都会停止 运行。我认为当效果 re-runs 时停止间隔更重要,否则每当效果再次运行时,您将开始一个新的间隔,从而导致多个并行间隔:
useEffect(() => {
if (Object.keys(someKey).length > 0) {
function callSvc(urls) {
}
callSvc(urls);
const intV = setInterval(callSvc, interval, urls);
return () => {
clearInterval(intV)
}
}
}, [someKey])