Ahmed Elabbasy
Ahmed Elabbasy

Reputation: 31

document.removeEventListener not fire in useEffect return

I use React transitions group with Router When moving to another page it does not remove the listener It only removes the listener when moving and reloading

function IntroPage() {

 function Herotilt(event) {
     var Tilt = document.getElementById("showcase-tilt");
     var maxTilt = 1.5;

     var xPos = (event.pageX / window.screen.width) * (maxTilt * 2) - maxTilt;
     var yPos = (event.pageY / window.screen.height) * (maxTilt * 2) - maxTilt;
     gsap.set(Tilt, { transformPerspective: 2000, transformOrigin: "center" });
     gsap.to(Tilt, 0.2, {
      rotationY: xPos,
      rotationX: yPos,
      ease: Power1.easeOut,
      overwrite: true,
    });
  }

  useEffect(() => { // start useEffect Hook

    document.addEventListener("mousemove", (event) => { //Start EventListener
    Herotilt(event);
    console.log("from Intro");
   }); // end EventListener

    return function cleanUp() { //start Clean Function
     console.log("Clean UP");
     document.removeEventListener("mousemove", Herotilt);
      }; // end Clean Function 

   }, []); // end useEffect Hook

} // end Function Component

Upvotes: 0

Views: 1611

Answers (2)

Tyler Smith
Tyler Smith

Reputation: 174

There are two things going on here:

  1. The cleanup function needs to be returned within the useEffect block (take a look at the docs here for an example).

  2. You can't remove event listeners that use anonymous functions, so you'll need to add Herotilt as directly to the addEventListener call. JavaScript will automatically pass the event into event listener callbacks.

Take a look at the code below. I've removed the Herotilt function body just to draw more attention to the actual fixes.

Hope this helps!

function IntroPage() {

 function Herotilt(event) {
     // Do stuff here...
  }

  useEffect(() => {
    // Pass in the function by name.
    document.addEventListener("mousemove", Herotilt);

    // The return block goes within useEffect().
    return function cleanUp() {
        console.log("Clean UP");
        document.removeEventListener("mousemove", Herotilt)
    };

 }, []);

Upvotes: 1

Józef Podlecki
Józef Podlecki

Reputation: 11283

I think you should save the lambda which you are creating in addEventListener to variable and pass it to removeEventListener instead

useEffect(() => {

  const callback = (event) => {
    Herotilt(event);
    console.log("from Intro");
  }

  document.addEventListener("mousemove", callback);
  return function cleanUp() {
    console.log("Clean UP");
    document.removeEventListener("mousemove", callback);
  };

}, []);

...or just pass Herotilt function without wrapping them in another function

Upvotes: 0

Related Questions