React: Can not prevent a child onClick event from the parent's onMouseUp event

Created on 8 Dec 2015  路  7Comments  路  Source: facebook/react

img_20151208_172309

I do click down, mouse move, and click up (all this events apply within element area).
Events onMouseDown, onMouseMove, onMouseUp defined on the parent element SwipePanel.
So I try prevent onClick event on Element component such way:

class SwipePanel extends React.Component {
  handleMouseUp(event) {
    if(event.nativeEvent) {
      event.nativeEvent.preventDefault();
      event.nativeEvent.stopPropagation();
    }
    event.preventDefault();
    event.stopPropagation();
    console.log('SwipePanel onMouseUp');
  }
  ...
}
class Element extends React.Component {
  handleMouseClick(event) {
    console.log('Element onClick');
  }
  ...
}

Via console.log I see

SwipePanel onMouseUp
Element onClick

So I need prevent childs's onClick event from parent component via onMouseUp. I am using React v0.14.3

Most helpful comment

@nodkz You can use onClickCapture in parent component and stopPropagation if event target is not child component.

https://facebook.github.io/react/docs/events.html#supported-events

All 7 comments

If I use touch device, onTouchEnd event perfectly prevents onClick by the code above.

@nodkz I think this is a general issue (not React specific)?

How about attaching mouseUp event to child and where preventing further propagation?

@mking it looks like bug and if it general issue, so it lack of specification. Because internally onClick works with onMouseDown and onMouseUp, otherwise it can not be realized such standard behavior: do mouse down on element, move mouse outside the element, and make mouse up (in such case onClick does not appear on the element).

@CoderK your solution can be implemented if number of children is low and this is incapsulated in some component. But In my case it can't be done, cause hundreds elements will be mount on the my SwipePanel and remember that in every component I should attach mouseUp event it looks strange and fraught with errors.

I need prevent onClick events for children, when I swipe/drag parent element SwipePanel. And this logic must be encapsulated in SwipePanel, children components do not need to know about preventing onClick.

@nodkz You can use onClickCapture in parent component and stopPropagation if event target is not child component.

https://facebook.github.io/react/docs/events.html#supported-events

@heineiuo thanks, works perfectly!

Another method that I've found to be quite straightforward for child onClick ignoring. Give the parent a unique ID. Perhaps "swipe-panel" in your example. Then In the parent's onClick:

handleMouseClick = event => {
  const target = event.target;
  if (target.id !== 'swipe-panel') {
    return ; // child was clicked, ignore onClick
  }

  // rest of click logic here

}
Was this page helpful?
0 / 5 - 0 ratings