Home > Blockchain >  React hook setState - setting an array (React Tic Tac Toe tutorial but with hooks)
React hook setState - setting an array (React Tic Tac Toe tutorial but with hooks)

Time:07-16

I've been trying to follow the react tic tac toe tutorial, but to use functional components instead of object components. Everything works beautifully until the backtracking part.

I've narrowed the problem down to the fact that in my handleClick function setHistory(hist) isn't actually changing the state of history. hist is an array of arrays here.

(I'm including only the game component for brevity, but if the whole file is needed, let me know.)

const Game= () => { 
    
    const [xIsNext, setXIsNext] = useState(true);
    const [history, setHistory] = useState(Array(Array(9).fill(null)));
    const [stepNumber, setStepNumber] = useState(0);

    function handleClick(i) {        
        const hist = history.slice(0, stepNumber 1);
        console.log(hist)
        setHistory(hist);
        console.log("in handleClick - log 1 - history size = "  history.length)

        const currentBoard = [...history[stepNumber]];
        const winner = calculateWinner(currentBoard);
        
        if (winner || currentBoard[i]) return;
        currentBoard[i] = xIsNext ? "X" : "O";
        setHistory(history.concat([currentBoard]));
        setStepNumber (stepNumber   1)
        setXIsNext(!xIsNext);

    }

    function jumpTo(move) {
        setXIsNext(move % 2 == 0)
        setStepNumber(move)
    }
    


    const currentBoard = [...history[stepNumber]];
    const winner = calculateWinner(currentBoard);

    const moves = history.map((step, move) => {
        const description = move ?
            ' Go to move #'   move :
            ' Go to game start';
        return (
            <li key={move}>
                <button onClick={() => jumpTo(move)} > {description} </button>
            </li>
        );
    })

    let status;
    if (winner) {
        status = winner   " WON !!!!";
    }
    else {
        status = 'Next player: '   (xIsNext ? "X" : "O");
    }




    return (
        <div className="game">
            <div className="game-board">
                <Board 
                    squares = {currentBoard} 
                    handleClick={handleClick}
                />
            </div>
            <div className="game-info">
                <div className="status">{status}</div>
                <ol>{moves}</ol>
            </div>
        </div>
    )
}

CodePudding user response:

States is not updated immediately in react hooks.

ex:

const [counter, setCounter]=useState(0);

handleClick(){
 //counter = 0
 setCounter(counter   1);
 console.log(counter); //counter is old state so it is still 0     
}

for your question: (history replace hist)

function handleClick(i) {        
    const hist = history.slice(0, stepNumber 1);
    const currentBoard = [...history[stepNumber]];
    const winner = calculateWinner(currentBoard);
    
    if (winner || currentBoard[i])
    {
        setHistory(hist);
        return;
    };
    currentBoard[i] = xIsNext ? "X" : "O";
    setHistory(hist.concat([currentBoard]));
    setStepNumber (stepNumber   1)
    setXIsNext(!xIsNext);

}
  • Related