reactjsonclickevent-propagation

How can I prevent event bubbling in nested React components on click?


Here's a basic component. Both the <ul> and <li> have onClick functions. I want only the onClick on the <li> to fire, not the <ul>. How can I achieve this?

I've played around with e.preventDefault(), e.stopPropagation(), to no avail.

class List extends React.Component {
  constructor(props) {
    super(props);
  }

  handleClick() {
    // do something
  }

  render() {

    return (
      <ul 
        onClick={(e) => {
          console.log('parent');
          this.handleClick();
        }}
      >
        <li 
          onClick={(e) => {
            console.log('child');
            // prevent default? prevent propagation?
            this.handleClick();
          }}
        >
        </li>       
      </ul>
    )
  }
}

// => parent
// => child

Solution

  • I had the same issue. I found stopPropagation did work. I would split the list item into a separate component, as so:

    class List extends React.Component {
      handleClick = e => {
        // do something
      }
    
      render() {
        return (
          <ul onClick={this.handleClick}>
            <ListItem onClick={this.handleClick}>Item</ListItem> 
          </ul>
        )
      }
    }
    
    class ListItem extends React.Component {
      handleClick = e => {
        e.stopPropagation();  //  <------ Here is the magic
        this.props.onClick();
      }
    
      render() {
        return (
          <li onClick={this.handleClick}>
            {this.props.children}
          </li>       
        )
      }
    }