是否可以在处理函数中删除和重新添加 React eventListener?

Is it possible to remove and readd React eventListener within the handler function?

我正在使用类似 fullpage.js 的 React,我需要在转换过程中删除 eventListener。

可能吗?

反应代码

function App() {
  const wheelHandler = (event) => {
     // I need to remove wheelHandler here

     setTimeout(() => {
       // I need to readd wheelHandler here
     }, 1000); // Assume that the transition ends after 1000ms
  };

  return (
    <div className="App" onWheel={wheelHandler} />
  );
}

等效于 Vanilla JS

const wheelHandler = (event) => {
  window.removeEventListener(wheelHandler);

  setTimeout(() => {
    window.addEventListener(wheelHandler);
  }, 1000);
};

window.addEventListener(wheelHandler);

P.S。我在 React 上尝试了 Vanilla JS 解决方案,但事件处理程序在一个滚轮上被多次触发。因此我别无选择,只能使用 React 的 SyntheticEvent。

通过连接它的方式,您不能不使用一个状态来告诉您是否连接处理程序和 re-rendering,这可能有点矫枉过正。

相反,我会设置一个标志(可能通过 ref 在对象上)告诉处理程序在您希望忽略调用的时间内忽略调用。

这些行很长:

function App() {
  const {current: scrolling} = useRef({flag: false});
  const wheelHandler = (event) => {
     // I need to remove wheelHandler here
     if (scrolling.flag) {
         // Bail out
         return;
     }
     scrolling.flag = true;

     // ...other logic if any...

     setTimeout(() => {
       // I need to readd wheelHandler here
       scrolling.flag = false;
     }, 1000); // Assume that the transition ends after 1000ms
  };

  return (
    <div className="App" onWheel={wheelHandler} />
  );
}

或者你也可以这样做,你不需要额外的对象(我倾向于使用一个 ref 来保存我所有的 non-state 实例数据,但你不需要必须):

function App() {
  const scrolling = useRef(false);
  const wheelHandler = (event) => {
     // I need to remove wheelHandler here
     if (scrolling.current) {
         // Bail out
         return;
     }
     scrolling.current = true;

     // ...other logic if any...

     setTimeout(() => {
       // I need to readd wheelHandler here
       scrolling.current = false;
     }, 1000); // Assume that the transition ends after 1000ms
  };

  return (
    <div className="App" onWheel={wheelHandler} />
  );
}

正如他们在 the useRef documentation 中所说,refs 对于 non-state 实例信息很有用:

However, useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.