0

I am building a tic tac toe game similar to the one used in the official tutorial for React. I am using these methods to handle clicks and to check if someone won. Right now my history is always one step behind and I can't figure out why. It won't say I have won until I do one more move.

  function didSomeoneWin(){
    const squares = history[history.length - 1].squares;
    console.log("history: ", history, " squares: ", squares);
    const lines = [
      [0,1,2],
      [3,4,5],
      [6,7,8],
      [0,3,6],
      [1,4,7],
      [2,5,8],
      [0,4,8],
      [6,4,2],
    ];
    lines.forEach((line) => {
      const [a,b,c] = line;
      if (squares[a] && squares[a] === squares[b] && squares[b] === squares[c]){
        console.log("SOMEONE WON!");
        setWinner( squares[a]); // return the winner: X or O
      }
    })
  }

  function squareClick(i){
    if (!winner){
      const current = history[history.length - 1];
      const squares = current.squares.slice();
      if (squares[i]){
        return;
      }
      squares[i] = turnCount;
      console.log(i);
      console.log("history before: ", history[history.length - 1]);
      setHistory(history.concat([{ squares: squares }]));
      console.log("history after: ", history[history.length - 1]);
      setTurnCount(history.length % 2 === 0 ? "X" : "O");   
      didSomeoneWin();
    }
  }

Thank you for your assistance.enter image description here

Meow Meow
  • 115
  • 10

1 Answers1

1

Setting state in React is always async. That means history will not be updated until the next render.

Either you should pass squares into didSomeoneWin and use it to determine a winner:

function squareClick(i){
  // code
  didSomeoneWin(squares)
}
function didSomeoneWin(squares) {
 // remove line fetching squares from history
 // code
}

or the call to didSomeoneWin should happen in a useEffect that runs after each render:

useEffect(() => { didSomeoneWin(); }, [history]);
// and add history as the dependency, so we only run `didSomeoneWin` if history changes
coagmano
  • 5,542
  • 1
  • 28
  • 41