In my React component, I have a event handling for beforeunload. I want to clean that up in my useEffect return. Is the below code the correct way of doing the same or is there any better way ?
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])
UPDATED CODE
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])
Is the below code the correct way of doing the same or is there any better way ?
There is a crucial problem with your code: Removing an event handler only works if you pass exactly the same function to removeEventListener
that you passed to addEventListener
. But as it stands you are passing two different functions. This is easy to solve buy storing the function in a variable and reference that variable in both addEventListener
and removeEventListener
.
However, I question whether the beforeunload
event handler is even necessary. When the page is closed any JS code stops running anyway. I think it's more important to stop the interval when the effect re-runs, otherwise you are starting a new interval whenever the effect runs again, resulting in multiple parallel intervals:
useEffect(() => {
if (Object.keys(someKey).length > 0) {
function callSvc(urls) {
}
callSvc(urls);
const intV = setInterval(callSvc, interval, urls);
return () => {
clearInterval(intV)
}
}
}, [someKey])