Why does parent onClick trigger before child onChange

Viewed 889

I have basic HTML in my React project that looks like this:

<div
  onClick={(e) => this.handleRowClick(e, id)}>
  <p>
    <input
      type="checkbox"
      onChange={this.handleSelectOneChange} />
  </p>
</div>

JS:

  handleRowClick(event, item_id) {
     // do stuff
  }

  handleSelectOneChange(event) {
    event.stopPropagation();
  }

When I click on the checkbox, it fires the handleRowClick also in the parent Div. Even though I have a stopPropagation() in the child function. However, when I log, it calls the parent function before the child (checkbox) function so I can see why stopPropagation() is not working.

Is there a better way to do this? Or will I just have to check what type of element is being clicked before doing anything. For example, in the parent click function, don't do anything if the "target" is a checkbox. Is seems like that is a hack and not the proper way to handle this.

2 Answers

It's very likely that clicking on the checkbox triggers a 'click' event that's bubbling up to the div. So you may want to capture the input click event before it bubbles.

How about trying this:

<input
  type="checkbox"
  onClick={this.handleCheckboxClick}
  onChange={this.handleSelectOneChange} />
this.handleCheckboxClick(evt) {
  event.stopPropagation();
}

This snippet shows the sequence of events. Clicking the checkbox produces these events in this order:

input onclick
div onclick
input onchange

<div onclick="console.log('div onclick');">
  Checkbox:
  <input type="checkbox"
    onclick="console.log('input onclick');"
    onchange="console.log('input onchange');" />
</div>

Surely the click event will hit . since the checkbox is wrapped in a div which has already a click event and the click event is having more priority than onChange, to handle the logic in here you have to use

e.target.id or e.target.name in order to identify the element.

Related