简体   繁体   中英

How to use useEffect Hook to execute the operation only once?

I wanted to make the modal popup if someone leaves the window.

I tried the following code:

React.useEffect(() => {
    const popupWhenLeave = (event) => {
      if (
        event.clientY <= 0 ||
        event.clientX <= 0 ||
        event.clientX >= window.innerWidth ||
        event.clientY >= window.innerHeight
      ) {
        handleClickOpen();
      }
    };
    document.addEventListener("mouseleave", popupWhenLeave);

    return () => {
      document.removeEventListener("mouseleave", popupWhenLeave);
    };
  }, []);

The above code helped me but became annoying as it pops up every interval. I tried adding a new state to run the code only once:

const [cursorOut, setCursorOut] = useState(false);

React.useEffect(() => {
    const popupWhenLeave = (event) => {
      if (
        event.clientY <= 0 ||
        event.clientX <= 0 ||
        event.clientX >= window.innerWidth ||
        event.clientY >= window.innerHeight
      ) {
        handleClickOpen();
      }
    };
    if(!cursorOut) {
       document.addEventListener("mouseleave", popupWhenLeave);
       setCursorOut(true);
    }

    return () => {
      document.removeEventListener("mouseleave", popupWhenLeave);
    };
  }, []);

The above code also ran the same as the previous one ie every time the modal would pop up.

I tried to add the dependency to useEffect [cursorOut] but now it won't pop the modal.

I need to pop up the modal only once on the page when the cursor is out and then stop.

PS I also tried without useEffect and it doesn't work.

Your useEffect function is only called once, when the dependency array is empty. However, your useEffect function adds an event listener to the page, which fill be called every time the event occurs .

If you want to only listen to the event once, you should remove the event listener in the popupWhenLeave function and not only in the useEffect clean up function you return at the end.

  React.useEffect(() => {
    const popupWhenLeave = (event) => {
      if (
        event.clientY <= 0 ||
        event.clientX <= 0 ||
        event.clientX >= window.innerWidth ||
        event.clientY >= window.innerHeight
      ) {
        handleClickOpen();
        document.removeEventListener("mouseleave", popupWhenLeave);
      }
    };
    document.addEventListener("mouseleave", popupWhenLeave);

    return () => {
      document.removeEventListener("mouseleave", popupWhenLeave);
    };
  }, []);

Sidenote: If your component is recreated because eg a parent component changed, the useEffect function will be called again regardless of the contents of the dependency array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM