0

Can someone help explain how to stop event propagation on a click? I've read many other posts, but I still can't figure it out.

I have a grid of 40x50 boxes, and when I click one I'd like to see that box's id. Currently, when I click it bubbles up and returns Board as what's been clicked. So I need to stop the propagation, right? Where/how do I do that? I've tried passing i.stopPropagation(); in the handleClick() method, but it tells me that i.stopPropagation(); isn't a function.

function Square(props) {
  return (
    <div className="square" id={props.id} onClick={props.onClick}/>
  );
}

class Board extends Component {
  rowsByColumns(rows, columns) {
    let arr=[];
    let k=0;
    let m=0
    for (let i=0;i<rows;i++) {
      arr.push([])
      for (let j=0;j<columns;j++) {
        arr[i].push(<Square key={"square"+m++} id={"square"+m} living={false} onClick={() => this.props.onClick(this)}/>)
      }
    }
    let newArr = arr.map(row => <Row key={"row"+k++}>{row}</Row>);
    return (newArr);
  }

  render() {
    return (
        <div id="board">
          {this.rowsByColumns(40,50)}
        </div>
    );
  }
}

class App extends Component {
  constructor() {
    super();
    this.state = {
      alive: ["square1"],
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(i) {
    console.log(i);
    this.setState({
      alive: this.state.alive.concat([i])
    })
  }

  render() {
    return (
      <div className="App container-fluid">
        <main className="row justify-content-center">
          <Board alive={this.state.alive} onClick={i => this.handleClick()}/>
          </div>
        </main>
      </div>
    );
  }
}
mackmmiller
  • 39
  • 1
  • 2
  • 6
  • Why is your `handleClick` accepting an `i` parameter you don't send it? – T.J. Crowder Nov 03 '17 at 19:25
  • 2
    Saying "*I've read many other posts, but I still can't figure it out.*" and then not telling us what you have read or why those posts didn't help you is like asking for duplicate flags. **Why** can you still not figure it out? **What** is still not working"? – zero298 Nov 03 '17 at 19:29
  • @zero298: Good catch (on the dupe), although the question there isn't very good. I wonder if there's a better one... – T.J. Crowder Nov 03 '17 at 19:30
  • @zero298: Found a slightly better one. – T.J. Crowder Nov 03 '17 at 19:31

1 Answers1

1

Your click handler receives an event object. Use stopPropagation on it:

handleClick(e) {
    e.stopPropagation();
}

then in your onClick:

onClick={this.handleClick}

Live example — the child stops every other click it sees:

class Parent extends React.Component {
  constructor(...args) {
    super(...args);
    this.handleClick = () => {
      console.log("Parent got the click");
    };
  }
  render() {
    return <div onClick={this.handleClick}>
      Click here to see parent handle it.
      <Child />
      </div>;
  }
}
class Child extends React.Component {
  constructor(...args) {
    super(...args);
    this.stopClick = true;
    this.handleClick = e => {
      if (this.stopClick) {
        e.stopPropagation();
        console.log("Child got the click and stopped it");
      } else {
        console.log("Child got the click and didn't stop it");
      }
      this.stopClick = !this.stopClick;
    };
  }
  render() {
    return <div onClick={this.handleClick}>I'm the child</div>;
  }
}

ReactDOM.render(
  <Parent />,
  document.getElementById("root")
);
<div id="root"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875