是否可以在处理函数中删除和重新添加 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.
我正在使用类似 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 theref
attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.