React onClick and onTouchStart fired simultaneously

There is a defined order of when the events get fired (source):

touchstart
Zero or more touchmove events, depending on movement of the finger(s)
touchend
mousemove
mousedown
mouseup
click

If you want to prevent a click event if a touch event is fired before, you can you can use event.preventDefault() in the touchend event handler to prevent the click event from firing.

function App() {
  const handleClick = () => {
    alert('click');
  };

  const handleTouchEnd = (event) => {
    alert('touchend');

    event.preventDefault();
  };

  return (
    <button
      type="button"
      onClick={handleClick}
      onTouchEnd={handleTouchEnd}
    >
      Click Me
    </button>
  );
}

However, this is not universally applicable. For example, you cannot prevent a click event by using a event.preventDefault() in a mousedown event. In case you are looking for a solution to this (not sure when this use case applies though), you would have to use a ref instead:

function App() {
  const prevent = React.useRef(false);

  const handleClick = () => {
    if (!prevent.current) {
      alert('click');
    } else {
      prevent.current = false;
    }
  };

  const handleMouseDown = () => {
    prevent.current = true;

    alert('mousedown');
  };

  return (
    <button
      type="button"
      onClick={handleClick}
      onMouseDown={handleMouseDown}
    >
      Click Me
    </button>
  );
}

This is a few years late but found a solution that was really easy to implement. Looks like this:

import ReactDom from 'react-dom';

export default class YourClass extends Component {

componentDidMount(){
        ReactDOM.findDOMNode(this).addEventListener('touchstart', (e)=>{ 
            e.preventDefault(); 
            console.log("touchstart triggered");
        });
    }
}

Seems like it intercepts and stops all onClick calls on mobile which is exactly what I was looking for


Solved this problem using similar events between touch and mouse. touchStart/mouseDown or touchEnd/mouseUp. It fires one or another, according to each situation.

<div
  className={myClasses}
  onMouseUp={this.myHandle}
  onTouchEnd={this.myHandle}
  >&nbsp;
</div>

To avoid onClick() on touch devices you should check if the page is opened in touch devices or not.

To check weather it is opened in touch devices or not:

if (typeof document !== 'undefined') {
  var isTouch = 'ontouchstart' in document.documentElement;
}

Then modify {isTouch ? undefined : this.myHandle} to your mouse event:

<div
  className={myClasses}
  onClick={isTouch ? undefined : this.myHandle}
  onTouchStart={this.myHandle}
  >&nbsp;
</div>