简体   繁体   中英

How to make setState update immediately in React

I completed the React tic-tac-toe tutorial . I then wanted to add some simple AI, so that when a player makes a move, the AI will answer.

However, when I click on a square to place an X, my move seems to be discarded and computer makes its move instead. So the state isn't updated immediately after my move and when AI makes it's move, it hasn't "seen" my move yet. I suspect it might be something to do with how onClick or setState function works in React but can't really get my finger on it. Maybe someone could point out the problem in my code?

Here are the relevant code bits:

handleClick(i) {
    const history = this.state.history;
    const current = history[history.length - 1];
    if (current.squares[i] || calculateWinner(current.squares)) {
        return;
    }

    const newSquares = current.squares.slice();
    newSquares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
        history: history.concat([{squares: newSquares}]),
        xIsNext: !this.state.xIsNext,
        step: history.length,
    });

    this.aiMove('O');
}

aiMove(mark) {
    const history = this.state.history;
    const current = history[history.length - 1];
    const newSquares = current.squares.slice();
    const ai = new Ai(mark);
    const targetSquare = ai.findBestMove(current.squares);
    newSquares[targetSquare] = mark;
    this.setState({
        history: history.concat([{squares: newSquares}]),
        xIsNext: !this.state.xIsNext,
        step: history.length,
    });
}

The handleClick function is same as in tutorial, except that i added this.aiMove('O'); on last line, which seems to mess things up. Here's my full code .

This turned out to be a problem of setState being async and not updating the state immediately. More info here: setState doesn't update the state immediately

I put the AI move as a callback function to the first setstate (player move) and that fixed the issue.

this.setState({
        history: history.concat([{squares: newSquares}]),
        xIsNext: !this.state.xIsNext,
        step: history.length,
    }, () => setTimeout(() => this.aiMove('O'), 1000));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM