Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - I can't stop propagation of a label click within a table

Tags:

reactjs

In the below example, I have a simple <table> with a checkbox inside it. I have click events on the td, tr and checkbox. I want to be able to click the checkbox and stop the bubbling to the td and tr. A simple "event.stopPropagation()" works great.

The problem is that if I want to connect a <label> to the checkbox using "htmlFor", the events won't stop bubbling when the label is clicked (even though it still works as expected with the checkbox itself is clicked). And even more strangely, the bubbling seems to happen in a weird order (as in Checkbox click is received last!).

Here's the code:

var Hello = React.createClass({
  func1(e){
    console.log('tr was clicked')
  },
  func2(e){
    console.log('td was clicked')
  },
  func3(e){
    e.stopPropagation();
    console.log('Checkbox was clicked')
  },
  render: function() {
    return <table>
        <tbody>
        <tr onClick={this.func1}>
          <td onClick={this.func2}>
            <input id="thing" type="checkbox" onClick={this.func3} />                                   
            <label htmlFor="thing"> label for checkbox</label>
          </td>
        </tr>
      </tbody>
    </table>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

...And here's the Fiddle: https://jsfiddle.net/69z2wepo/52785/ (View the console for the click events)

like image 270
Andrew Avatar asked Aug 15 '16 15:08

Andrew


People also ask

How do I stop click event propagation?

To stop an event from further propagation in the capturing and bubbling phases, you call the Event. stopPropation() method in the event handler. Note that the event. stopPropagation() method doesn't stop any default behaviors of the element e.g., link click, checkbox checked.

How do you stop propagation in react?

event.stopPropagation() This will stop any parent component's event from firing. To use this: Make sure to pass the event object as a parameter. Use the stopPropagation method on the event object above your code within your event handler function.

How do I stop event bubbling in react?

React: stopPropagation We extended one of the previous examples by using the stopPropagation() method on an event. This way, when the button gets clicked, the event does not bubble up and does not trigger the event handler of the surrounding container element.

Which method can be used to stop propagation of an event?

Event.stopPropagation() The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.


1 Answers

The label doesn't have a click handler of it's own, and can't stop propagation, so when you click the label normal event bubbling takes place. This means that all the parent's event handlers are invoked in the correct order. In addition, because of the htmlFor, the checkbox click handler is also triggered, but not as part of the event bubbling.

To solve the problem, add a separate click handler to the label that only includes .stopPropgation() (demo):

var Hello = React.createClass({
  func1(e){
    console.log('tr was clicked')
  },
  func2(e){
    console.log('td was clicked')
  },
  func3(e){
    e.stopPropagation();
    console.log('Checkbox was clicked')
  },
  stopLabelPropagation(e) {
    e.stopPropagation();
  },
  render: function() {
    return <table>
        <tbody>
        <tr onClick={this.func1}>
          <td onClick={this.func2}>
            <input id="thing" type="checkbox" onClick={this.func3} />                                     
            <label htmlFor="thing" onClick={ this.stopLabelPropagation }>label for checkbox</label>
          </td>
        </tr>
      </tbody>
    </table>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);
like image 152
Ori Drori Avatar answered Sep 22 '22 18:09

Ori Drori