Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React onWheel handler can't preventDefault because it's a passive event listener

I'm trying to override Ctrl+scroll behavior on a component, but it's not working with the error [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See <URL>. I think I'm okay with using an active listener, so is there a way to specify that through React? Note that I need to access and modify state within 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>);
like image 557
Jeff Demanche Avatar asked Dec 02 '25 20:12

Jeff Demanche


1 Answers

A bit late, but maybe it helps someone else.

The problem is that React uses passive event handlers by default with wheel, touchstart and touchmove events - in other words, you can't call stopPropagation within them.

If you want to use non-passive event handlers, you need to use refs and add/remove event handler manually, like this:

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();
    // ...
  }

  // ...
}

Should be similar with hooks.

like image 76
johndodo Avatar answered Dec 05 '25 09:12

johndodo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!