未在useEffect返回中触发document.removeEventListener

时间:2020-06-21 20:38:08

标签: javascript reactjs dom

我在路由器上使用React Transitions组 移到另一个页面时,它不会删除侦听器 仅在移动和重新加载时删除监听器

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

2 个答案:

答案 0 :(得分:1)

这里发生了两件事:

  1. 需要在useEffect块(take a look at the docs here for an example)中 返回清理功能。

  2. 您无法删除使用匿名函数的事件侦听器,因此您需要将Herotilt直接添加到addEventListener调用中。 JavaScript会自动将事件传递到事件侦听器回调中。

看看下面的代码。我删除了Herotilt函数主体只是为了引起人们对实际修复的更多关注。

希望这会有所帮助!

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)
    };

 }, []);

答案 1 :(得分:0)

我认为您应该将在addEventListener中创建的lambda保存为变量,然后将其传递给removeEventListener

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);
  };

}, []);

...或者只传递Herotilt函数而不将它们包装在另一个函数中