Handling Events with React - example with the Game of Life project

Handling Events with React - example with the Game of Life project
0

#1

Here is my Game of Life project
In this react project we have to make the cells clickable.
I am handling the things like this :

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

class Game extends React.Component {
(...)
  handleCellClick(c) { (...) }
  
  render {
    (...)
    const cells = this.state.matrice.map((cell, index) => {
      return (
        <Square color={cell} ref={index} onClick={() => this.handleCellClick(index)} />
      );
    });
  }
}

It’s working fine BUT looking at react documentation on handling event I am afraid I am in the situation they give a warning about :

The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor to avoid this sort of performance problem.

Therefore I tried to modify my code as follow :

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

class Game extends React.Component {
  constructor(props) {
    super(props);
    (...)
    this.handleCellClick = this.handleCellClick.bind(this);
  }
  handleCellClick(c) { (...) }
  
  render {
    (...)
    const cells = this.state.matrice.map((cell, index) => {
      return (
        <Square color={cell} ref={index} onClick={this.handleCellClick(index)} />
      );
    });
  }
}

but this is absolutely not working.

Can you confirm that my first version is actually doing some extra re-rendering lowering the performance ?
If yes how can I correct it using binding ?


#2

I’m not a react expert, but I ran into a similar situation in my markdown previewer (App component is the parent)

AFAIK it’s not the best practice to lift state of component to it’s parent, but your second code looks fine to me.
Maybe you should write onClick={this.handleCellClick} instead of onClick={this.handleCellClick(index)} ?
I’m just guessing here, but maybe my example will help you a bit…


#3

This invokes the function, binding the return value rather than the function itself. You were fine with the first way you had it. I think the warning in the docs just means that every time the square re-renders, the function passed to onClick is different, which would trigger its own children to re-render unnecessarily.


#4

Re-reading the doc after reading your message I think you’re right, it would be an issue only if Square was passing this callback to one of his child possibly causing an extra rendering, but that’s not the case here.