在屏幕上呈现的状态总是落后一步

时间:2021-01-26 22:40:48

标签: javascript reactjs react-hooks

我正在尝试使用功能组件创建一个简单的井字游戏。但是,我似乎有一个问题,即我的状态总是在第一次点击方块时落后一步。我知道这个问题已经被问过很多次了,我已经阅读了很多帖子,但我仍然在努力让我的状态同步。我还注意到,当我调用我的电路板重置函数而不是从 X 开始时,它应该尝试从 O 开始,这在技术上是不可能的,因为它被设置回初始状态。任何人的任何帮助或建议将不胜感激!

App.js

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

import Board from './Board/Board';
import { calculateWinner } from '../shared/utils';
import { DEFAULT_BOARD } from '../shared/constants';
import './App.css';

const App = () => {
    const [state, setState] = useState({
        squares: Array(9).fill(null),
        stepNumber: 0,
        xIsNext: true,
        status: "Next player: X",
        moves: 0
    });

    useEffect(() => {
        const winner = calculateWinner(state.squares);
        if(winner) {
            setState((prevState) => ({
                ...prevState,
                status: 'Winner: ' + winner
            }));
        }
        if(state.moves >= 9) {
            setState((prevState) => ({
                ...prevState,
                status: 'Its a draw!'
            }));
        }
    }, [state.squares, state.moves]);

    const resetBoard = () => {
        setState({...DEFAULT_BOARD});
    }

    const handleClick = (i) => {
        const tempSquares = state.squares.slice();
        if (calculateWinner(tempSquares) || tempSquares[i]) {
          return;
        }
        let temp = !state.xIsNext
        tempSquares[i] = state.xIsNext ? 'X' : 'O';
        setState((prevState) => ({
            ...prevState,
            xIsNext: temp,
            moves: state.moves + 1,
            squares: tempSquares,
            status: 'Next player: ' + (state.xIsNext ? "X" : "O")
        }))
    }
    
    return (
        <div className="game">
            <Board handleClick={handleClick} status={state.status} squares={state.squares} resetBoard={resetBoard}/>
        </div>
    );
}

export default App;

Board.js


import Square from '../Square/Square';
import './Board.css';

const Board = ({status, handleClick, squares, resetBoard}) => {
    const renderSquare = (i) => {
        return (
            <Square value={squares[i]} onClick={handleClick} index={i} />
          );
    }

    return (
        <Fragment>
            <div className="board">
                <div className="status">{status}</div>
                <div className="board-grid">
                    {squares.map((value, index) => {
                        return (
                            <div key={index}>
                                {renderSquare(index)}
                            </div>
                        )
                    })}
                </div>
                <button onClick={resetBoard}>Reset Board</button>
            </div>
        </Fragment>
    )
}

export default Board;

Square.js

import React from 'react';

import './Square.css'

const Square = ({onClick, value, index}) => {
    return (
        <button className="square" onClick={() => onClick(index)}>
            {value}
        </button>
    )
}

export default Square;

util.js

export const calculateWinner = (squares) => {
    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6],
      ];
      for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
          return squares[a];
        }
      }
      return null;
}

常量.js

export const DEFAULT_BOARD = {
    squares: Array(9).fill(null),
    xIsXNext: true,
    status: "Next player: X",
    moves: 0
}

0 个答案:

没有答案