2

I have a component below: there are 2 usecases, when I click on the entire div some function is executed and when I click on just the <img>, some function is executed. I have 2 props defined, onClick, when clicked on the entire div and onIconClick when clicked on the img.

export default class List extends React.Component {
  onClick() {
    this.props.onClick();
  }
  onIconClick() {
    this.props.onIconClick();
  }
  render() {
    return (
      <div style="width:200px, height: 200px" onClick={this.onClick.bind(this)}>
        <img src="delete.png" onClick={this.onIconClick.bind(this)} />
      </div>
    );
  }
}

here is the way I call the component:

export default class MyApp extends React.Component {
  onClick() {
    //some execution
  }
  onIconClick() {
    //some other execution
  }
  render() {
    return (
      <List
        onClick={this.onClick.bind(this)}
        onIconClick={this.onIconClick.bind(this)}
      />
    );
  }
}

Now my issue is the this.onClick.bind(this) gets called all the time even when I click the image, hence I never get to this.onIconClick.bind(this).

I tried reversing the order:

 <List onIconClick={this.onIconClick.bind(this)} onClick={this.onClick.bind(this)} />

still doesn't work, not sure what selection criteria I should use in order to distinguish between these 2 clicks.

Any ideas??

2
  • why those event handlers are defined outside of classes? Commented Oct 23, 2018 at 0:47
  • my bad, fixed it! Commented Oct 23, 2018 at 0:54

2 Answers 2

4

Try this:

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
    this.onIconClick = this.onIconClick.bind(this);
  }
  onClick() {
    alert("Parent-onClick()");
  }
  onIconClick() {
    alert("Parent-onIconClick()");
  }
  render() {
    return (
      <div>
        <Child onClick={this.onClick} onIconClick={this.onIconClick} />
      </div>
    );
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
    this.onIconClick = this.onIconClick.bind(this);
  }
  onClick() {
    this.props.onClick();
  }
  onIconClick(e) {
    e.stopPropagation();
    this.props.onIconClick();
  }
  render() {
    let styles = {
      height: "500px",
      backgroundColor: "blue",
      paddingTop: "20px"
    };
    return (
      <div onClick={this.onClick} className="img-wrapper" style={styles}>
        <img
          onClick={this.onIconClick}
          src="https://via.placeholder.com/350x150"
          alt="img"
        />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Parent />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"><div>

The idea is using stopPropagation() method of the SyntheticEvent instance.


Your event handlers will be passed instances of SyntheticEvent, a cross-browser wrapper around the browser’s native event. It has the same interface as the browser’s native event, including stopPropagation() and preventDefault(), except the events work identically across all browsers.

If you find that you need the underlying browser event for some reason, simply use the nativeEvent attribute to get it.


Using the SyntheticEvent 's methods allows our code to behave exactly the same across all browsers.

Sign up to request clarification or add additional context in comments.

Comments

2

You can use e.stopPropagation(). If you want to use e.nativeEvent.stopImmediatePropagation(), you can use in the same line.

onIconClick(e) {
    e.stopPropagation();
    //e.nativeEvent.stopImmediatePropagation();
    this.props.onIconClick();
  }

1 Comment

where do I add this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.