skip to Main Content

I am trying to go through the react tutorial here: https://react.dev/learn/tutorial-tic-tac-toe

I am early on when it just is trying to pass a value to the handleClick function for which square to set to ‘X’.

For some reason, the onSquareClick={() => handleClick(1)} syntax (or whichever square value is passed for a given square) does not get passed into handleClick. I can breakpoint in the function in the browser and clicking in a square gets to the handler, but the parameter value is undefined according to the browser dev tools, and so I never succeed in setting a square to X. For curiosity I tried adding a specific handleClick0 function that doesn’t take a parameter and always sets X in box 0, and that works fine. My complete code is below. I am pretty sure it matches the tutorial at that step of the tutorial, but I cannot understand what I have wrong that the value is never passed into the handler. I also get that later in the tutorial the code gets improved in many ways, but at this early point I thought it should work as copied in from that step of the tutorial, but in the handler the browser says i is undefined when I hit the breakpoint there after clicking on any of squares 1 through 8. I don’t know if this matters but I am using Chrome.

import React  from 'react';
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick} >
      {value}
    </button>
  );
}

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));
   function handleClick({i}) {
    const nextSquares = squares.slice();
    nextSquares[{i}] = "X";
    setSquares(nextSquares);
}

function handleClick0() {
  const nextSquares = squares.slice();
  nextSquares[0] = "X";
  setSquares(nextSquares);
}

return (
    <React.Fragment>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={handleClick0} /> 
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </React.Fragment>
  );
}

I was expecting that I would have a value that was passed in in the handleClick function.

2

Answers


  1. Chosen as BEST ANSWER

    Found it. I am still learning the syntax and I should not have had the function declared as

    function handleClick({i})
    

    with the curly braces in there. It should have been:

    function handleClick(i)
    

  2. In your handleClick function, you have {i} in a few places where it should just be i. You use the {i} syntax within a JSX block to get the variable’s value, but inside a function like handleClick you can just use i directly:

    function handleClick({i}) {  // extra { } around the i
        const nextSquares = squares.slice();
        nextSquares[{i}] = "X";  // extra { } around the i
        setSquares(nextSquares);
    }
    

    So you want this instead:

    function handleClick(i) {
        const nextSquares = squares.slice();
        nextSquares[i] = "X";
        setSquares(nextSquares);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search