Search code examples
javascriptreactjsdomonclickonchange

Why does parent onClick trigger before child onChange


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.


Solution

  • 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>