我正在尝试覆盖组件上的 Ctrl+滚动行为,但它无法处理错误
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See <URL>
。我认为我可以使用主动侦听器,那么有没有办法通过 React 来指定它?请注意,我需要访问和修改 onWheel
内的状态。
const onWheel = (e: React.WheelEvent): void => {
if (e.altKey) {
e.preventDefault();
// Error
} else if (e.ctrlKey) {
e.preventDefault();
// Error
}
};
...
return (<div className={styles["workspace"]} onWheel={onWheel}>
stuff
</div>);
有点晚了,但也许对其他人有帮助。
问题在于 React 默认使用被动事件处理程序,其中包含 Wheel、touchstart 和 touchmove 事件 - 换句话说,您无法在其中调用
stopPropagation
。
如果你想使用非被动事件处理程序,你需要使用 refs 并手动添加/删除事件处理程序,如下所示:
class MyComponent extends React.Component {
myRef = React.createRef();
componentDidMount() {
// IMPORTANT: notice the `passive: false` option
this.myRef.current.addEventListener('wheel', this.handleWheel, { passive: false });
}
componentWillUnmount() {
this.myRef.current.removeEventListener('wheel', this.handleWheel, { passive: false });
}
handleWheel = (e) => {
e.stopPropagation();
// ...
}
// ...
}
应该和钩子类似。
对于任何使用功能组件的人来说,这里有一个解决方案,灵感来自@johndodo
function MyComponent {
const onWheel = useCallback(
(e) => {
console.log(e);
e.preventDefault();
},
[],
);
const divRef = useCallback(
(node) => {
console.log(node);
node.addEventListener('wheel', onWheel, { passive: false });
},
[onWheel],
);
return <div ref={divRef}>...</div>;
}
使用
useCallback
代替 divRef
+ useRef
的原因是 this。