Home > Enterprise >  window.removeEventListener not working in React
window.removeEventListener not working in React

Time:09-27

I am trying to block tab refresh/closing when a user is editing the page. This is stored in state. I have a useEffect that is triggered whenever the isEditing state changes:

const [isEditing, setIsEditing] = useState<boolean>(false);

const handleBrowserCloseReload = (e: any) => {
    e.preventDefault();
    return (e.returnValue = '');
  };

useEffect(() => {
    if (isEditing) {
      window.addEventListener('beforeunload', handleBrowserCloseReload);
    } else {
      console.log('remove');
      window.removeEventListener('beforeunload', handleBrowserCloseReload);
    }
  }, [isEditing]);

The problem is even when the 'remove' is logged to the console, I still get the prompt to save changes. Another question is does anyone know the type of the event for this? I do not want to leave it as "any"

CodePudding user response:

Don't bother with an else case, just return a "cleanup" function that removes the handler. When the component re-renders, the cleanup function will run. If you only attach when isEditing is true, then when it is false it won't get added. Plus you have the benefit that if that component unmounts but the page isn't unloaded, the cleanup will also run.

Just make sure to define your handleBrowserCloseReload handler within the useEffect hook so you can reuse the reference.

const [isEditing, setIsEditing] = useState<boolean>(false);

useEffect(() => {
    const handleBrowserCloseReload = (e: any) => {
      e.preventDefault();
      return (e.returnValue = '');
    };

    if (isEditing) {
      window.addEventListener('beforeunload', handleBrowserCloseReload);
    }
    
    return () => {
      console.log('remove');
      window.removeEventListener('beforeunload', handleBrowserCloseReload);
    };
}, [isEditing]);

CodePudding user response:

Anyone finding this similar issue, it was fixed with memoizing the handleBrowserCloseReload function:

const handleBrowserCloseReload = useMemo(() => {
    return (e: any) => {
      e.preventDefault();
      return (e.returnValue = '');
    };
  }, []);
  • Related