En mi componente React, tengo un manejo de eventos para beforeunload. Quiero limpiar eso en mi declaración useEffect. ¿Es el siguiente código la forma correcta de hacer lo mismo o hay alguna forma mejor?
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])CÓDIGO ACTUALIZADO
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])¿Es el siguiente código la forma correcta de hacer lo mismo o hay alguna forma mejor?
Hay un problema crucial con su código: eliminar un controlador de eventos solo funciona si pasa exactamente la misma función a removeEventListener que pasó a addEventListener . Pero tal como está, estás pasando dos funciones diferentes. Esto es fácil de resolver: almacene la función en una variable y haga referencia a esa variable tanto en addEventListener como en removeEventListener .
Sin embargo, me pregunto si el controlador de eventos beforeunload es necesario. Cuando se cierra la página, cualquier código JS deja de ejecutarse de todos modos. Creo que es más importante detener el intervalo cuando el efecto se vuelve a ejecutar, de lo contrario, está comenzando un nuevo intervalo cada vez que el efecto se vuelve a ejecutar, lo que da como resultado múltiples intervalos paralelos:
useEffect(() => { if (Object.keys(someKey).length > 0) { function callSvc(urls) { } callSvc(urls); const intV = setInterval(callSvc, interval, urls); return () => { clearInterval(intV) } } }, [someKey])Esta es la forma correcta de return una función dentro del bloque if, useEffect() limpiará solo si la condición en la declaración if es true , pero cuando no hay un oyente para agregar, no es necesario limpiar en el nivel superior dentro de la función useEffect() .
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.") } },[]) Luego pruebe cambiar la página montando/desmontando (actualmente estoy usando react-router-dom ) y luego mire la consola.
si la condición es true
Listener Added. Listener Removed. (Inside If statement) Si la condición es false
No Listener to Remove. Si el booleano es true , la función devolverá la función dentro del bloque if solamente, no fluirá hacia el retorno externo, excepto que el booleano sea false , el código regresará al nivel externo.