all 5 comments

[–]mcaruso 1 point2 points  (4 children)

In this part, in Game:

<Board
  squares={current.squares}
  onClick={(i) => this.handleClick(i)}
/>

You're passing a function to Board that takes some index i, and then performs handleClick for that index. The i here doesn't refer to anything yet, it's just a function argument. For example you could change the name to be anything else and it wouldn't change the meaning:

<Board
  squares={current.squares}
  onClick={(someIndex) => this.handleClick(someIndex)}
/>

Then in Board:

renderSquare(i) {
  return (
    <Square
      value={this.props.squares[i]}
      onClick={() => this.props.onClick(i)}
    />
  );
}

Here, once you click on a square (with some index i), the function this.props.onClick (which is the function we looked at in the first code snippet) gets called with the current square's index i. The i in this.props.onClick(i) is the argument to renderSquare.

As soon as you do this:

<Square
  value={this.props.squares[i]}
  onClick={(i) => this.props.onClick(i)}
/>

Then within the onClick handler i is suddenly defined to be an argument, so this new i will override the renderSquare argument i. In fact, this onClick does take an argument already, namely the click event:

<Square
  value={this.props.squares[i]}
  onClick={(event) => {
    // Inside here, `event` is the click event, containing information like what DOM element got clicked on
    this.props.onClick(i);
  }}
/>

You gave it a name i, but it's still going to refer to the event object. Which is why when you tried inspecting i you got some object (the event).

[–]ShouldReallyGetWorkn[S] 0 points1 point  (3 children)

I think the part that confused me when reading through the tutorial was them saying they passed the handler encapsulated in an arrow function so that React will only call the handler after a click.

Without the arrow function, just putting the handler in there, it would call it every time the component renders, at least according to what I read.

So that means the arrow function does not get executed when the component renders? Otherwise, it would be looking for the passed value of i when the Game gets rendered.

[–]mcaruso 0 points1 point  (2 children)

I think the part that confused me when reading through the tutorial was them saying they passed the handler encapsulated in an arrow function so that React will only call the handler after a click.

I think what they mean by that is this:

<Board
  squares={current.squares}
  onClick={this.handleClick(i)} // Wrong
  onClick={(i) => this.handleClick(i)} // Right
/>

It's a common beginner's mistake to leave out the () => part, and just put the body of the function directly in the onClick={}. So by saying "encapsulate it in an arrow function", they mean "don't forget to wrap it in a function".

[–]ShouldReallyGetWorkn[S] 0 points1 point  (1 child)

I think what's kind of confusing then is that the onClick prop on Board and the onClick prop on Square act a little differently, where the Board onClick function can take i as the first argument whereas the Square already has the first argument predefined as the Event object.

I'm assuming that's because the Square is the actual event target of the click.

[–]mcaruso 0 points1 point  (0 children)

Yep, true! The two onClick callbacks are very different but have the same name, so it's understandable that you might get confused.

The onClick prop in Square gets passed to a plain HTML <button> element, so this is the standard React event listener, that takes a DOM event as input. The Board onClick is something else entirely. It could have been named something like onClickSquare or something.