TicTacToe 反应 - 序列突出显示

问题描述 投票:0回答:1
任何人都可以研究我的代码并告诉我如何在 Tic Tac Toe 游戏中突出显示序列吗?

下面是我的代码。

Board.jsx

import React, {useState } from "react"; import Square from "../Square/Square"; import classes from "./Board.module.css"; const Board = () =>{ const [state, setState] = useState(Array(9).fill(null)); const [isXTurn, setIsXTurn] = useState(null); const [playerSymbol, setPlayerSymbol] = useState(null); const [winningSequence, setWinningSequence] = useState([]); const checkWinner = () => { const winnerLogic = [ [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 logic of winnerLogic){ const [a, b, c] = logic; if(state[a] != null && state[a] === state[b] && state[a] === state[c]){ // setWinningSequence([a,b,c]) // console.log(winningSequence) return state[a]; } } // setWinningSequence([]); return false; } const isWinner = checkWinner() const squareClickHandler = (index) => { if (state[index] != null || isWinner){ return; } const copyState = [...state] copyState[index] = isXTurn ? "X" : "O" setState(copyState); setIsXTurn(!isXTurn) } const handlePlayAgain = () => { setState(Array(9).fill(null)) setIsXTurn(null) setPlayerSymbol(null) setWinningSequence([]) } const handleSymbolSelection = (symbol) => { if (symbol === "X"){ setIsXTurn(true); }else{ setIsXTurn(false); } setPlayerSymbol(symbol); }; const renderSymbolSelection = () => { return ( <center> <h2>Select Your Symbol</h2> <button onClick={() => handleSymbolSelection("X")}>X</button> <button onClick={() => handleSymbolSelection("O")}>O</button> </center> ); }; const renderSquare = (index) => { // console.log(winningSequence) const isWinningSquare = winningSequence.includes(index); return ( <Square key={index} onClick={() => squareClickHandler(index)} value={state[index]} isWinningSquare={isWinningSquare} /> ); }; return ( <div className={classes["board-container"]}> {!playerSymbol ? ( renderSymbolSelection() ) : isWinner ? ( <> <center> {isWinner} Won the Game <button onClick={handlePlayAgain}>Play Again</button> </center> <div className={classes["board-row"]}> {renderSquare(0)} {renderSquare(1)} {renderSquare(2)} </div> <div className={classes["board-row"]}> {renderSquare(3)} {renderSquare(4)} {renderSquare(5)} </div> <div className={classes["board-row"]}> {renderSquare(6)} {renderSquare(7)} {renderSquare(8)} </div> </> ) : ( <> <center> <h4>Player {playerSymbol} please move!</h4> </center> <div className={classes["board-row"]}> {renderSquare(0)} {renderSquare(1)} {renderSquare(2)} </div> <div className={classes["board-row"]}> {renderSquare(3)} {renderSquare(4)} {renderSquare(5)} </div> <div className={classes["board-row"]}> {renderSquare(6)} {renderSquare(7)} {renderSquare(8)} </div> </> )} </div> ); }; export default Board;
Square.jsx

import React, { memo } from "react"; import classes from "./Square.module.css"; const Square = ({ value, onClick, isWinningSquare }) => { const squareClassName = `${classes.square} ${isWinningSquare ? classes.winning : ""}`; return ( <div className={squareClassName} onClick={onClick}> <h2>{value}</h2> </div> ); }; export default memo(Square);
尝试创建获胜序列状态

const [winningSequence, setWinningSequence] = useState([]);
在 checkWinner 函数中,当我尝试在 WinningSequence 数组中添加元素时,出现无限渲染错误。

我需要使用 useEffect 或 useCallback 之类的东西吗?

for (let logic of winnerLogic){ const [a, b, c] = logic; if(state[a] != null && state[a] === state[b] && state[a] === state[c]){ // setWinningSequence([a,b,c]) // console.log(winningSequence) return state[a]; } }
    
reactjs react-hooks frontend tic-tac-toe
1个回答
0
投票
这是一个固定示例:(未对

Square.js

 进行任何更改)

    将获胜序列移到组件之外,使它们成为全局的。 (轻微优化)
  1. 您正在混合
  2. isWinner
     变量来表示 
    isThereAWinner
    whoIsTheWinner
    。这是一个 hack-y 解决方案,但是还可以。
  3. 每次状态更改后使用
  4. useEffect
     主动检查获胜序列。
  5. 确保
  6. .winning
     css 类位于 css 中默认 
    .square
     类之后(如果后者已设置背景颜色)。
import React, { useCallback, useEffect, useState } from "react"; import classes from "./Board.module.css"; import Square from "./Square"; const winnerLogic = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; const Board = () => { const [state, setState] = useState(Array(9).fill(null)); const [isXTurn, setIsXTurn] = useState(null); const [playerSymbol, setPlayerSymbol] = useState(null); const [winningSequence, setWinningSequence] = useState([]); const [isWinner, setIsWinner] = useState(null); const checkWinner = useCallback(() => { for (let logic of winnerLogic) { const [a, b, c] = logic; if (state[a] != null && state[a] === state[b] && state[a] === state[c]) { setWinningSequence([a, b, c]); return state[a]; } } setWinningSequence([]); return false; }, [state]); useEffect(() => { setIsWinner(checkWinner()); }, [state, checkWinner]); const squareClickHandler = (index) => { if (state[index] != null || isWinner) { return; } const copyState = [...state]; copyState[index] = isXTurn ? "X" : "O"; setState(copyState); setIsXTurn(!isXTurn); }; const handlePlayAgain = () => { setState(Array(9).fill(null)); setIsXTurn(null); setPlayerSymbol(null); setWinningSequence([]); }; const handleSymbolSelection = (symbol) => { if (symbol === "X") { setIsXTurn(true); } else { setIsXTurn(false); } setPlayerSymbol(symbol); }; const renderSymbolSelection = () => { return ( <center> <h2>Select Your Symbol</h2> <button onClick={() => handleSymbolSelection("X")}>X</button> <button onClick={() => handleSymbolSelection("O")}>O</button> </center> ); }; const renderSquare = (index) => { // console.log(winningSequence) const isWinningSquare = winningSequence.includes(index); console.log(winningSequence.includes(index)); return ( <Square key={index} onClick={() => squareClickHandler(index)} value={state[index]} isWinningSquare={isWinningSquare} /> ); }; return ( <div className={classes["board-container"]}> {!playerSymbol ? ( renderSymbolSelection() ) : isWinner ? ( <> <center> {isWinner} Won the Game{" "} <button onClick={handlePlayAgain}>Play Again</button> </center> <div className={classes["board-row"]}> {renderSquare(0)} {renderSquare(1)} {renderSquare(2)} </div> <div className={classes["board-row"]}> {renderSquare(3)} {renderSquare(4)} {renderSquare(5)} </div> <div className={classes["board-row"]}> {renderSquare(6)} {renderSquare(7)} {renderSquare(8)} </div> </> ) : ( <> <center> <h4>Player {playerSymbol} please move!</h4> </center> <div className={classes["board-row"]}> {renderSquare(0)} {renderSquare(1)} {renderSquare(2)} </div> <div className={classes["board-row"]}> {renderSquare(3)} {renderSquare(4)} {renderSquare(5)} </div> <div className={classes["board-row"]}> {renderSquare(6)} {renderSquare(7)} {renderSquare(8)} </div> </> )} </div> ); }; export default Board;
    
© www.soinside.com 2019 - 2024. All rights reserved.