我正在构建一个井字游戏,并且能够让两个玩家互相玩。现在我想在Play O上模拟随机性。随机性的一部分是让9个子组件之一“PositionedComponent”模拟计算机进行点击并让它改变显示。
我认为使用useRef()和.click()可以实现这种模拟。我创建了一个useRef()数组,在每个PositionedComponent中,我给予它们一个useRef()。然后在useEffect()中,我想到创建一个随机数,然后在autoClick[randomValue]. current.click()中调用click函数。
我总是为autoClick得到一个未定义的值,但我不知道为什么当我在顶部初始化它时。
我还尝试将数组声明为autoClick = useState(Array(9).fill(useRef(),以及执行autoClick = [useRef()...,useRef()],但仍然存在未定义值的问题。
我尝试使用的另一个方法是document.getElementById(“”),但仍然是相同的未定义值问题。我不知道是什么问题,因为我在顶部声明了autoClick,但仍然得到未定义值。谢谢你的任何建议。
function TicTacToeGrid()
{
// Your tic-tac-toe logic goes here
const [playersMove, setPlayersMove] = useState(true);
const [symbol, setSymbol] = useState('');
const [currPosition, setCurrPosition] = useState(23)
const [board, setBoard] = useState(Array(9).fill('-'));
const [game, setGame] = useState(false)
const [tie, setTie] = useState(false)
const autoClick = []
for(let i = 0; i < 9; i++)
{
autoClick[i] = useRef();
}
const handlePlayersTurn = async (position) =>
{
console.log("auto click is", autoClick)
if(playersMove)
{
setSymbol('X')
}
else
{
setSymbol('O')
}
setPlayersMove(!playersMove)
setCurrPosition(position)
};
const positon1 = <PositionedComponent x="0px" y = "0px" ref={autoClick[0]} playersMove={playersMove} handlePlayersTurn={() => handlePlayersTurn(1)}/>
const positon2 = <PositionedComponent x="210px" y = "0px" ref={autoClick[1]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(2)}/>
const positon6 = <PositionedComponent x="420px" y = "0px" ref={autoClick[2]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(3)}/>
const positon3 = <PositionedComponent x="0px" y = "210px" ref={autoClick[3]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(4)}/>
const positon4 = <PositionedComponent x="210px" y = "210px" ref={autoClick[4]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(5)}/>
const positon7 = <PositionedComponent x="420px" y = "210px" ref={autoClick[5]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(6)}/>
const positon5 = <PositionedComponent x="0px" y = "420px" ref={autoClick[6]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(7)}/>
const positon9 = <PositionedComponent x="210px" y = "420px" ref={autoClick[7] playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(8)}/>
const positon8 = <PositionedComponent x="420px" y = "420px" ref={autoClick[8]} playersMove={playersMove} handlePlayersTurn={() =>handlePlayersTurn(9)}/>
useEffect(()=>
{
if(playersMove)
{
console.log("X turn")
}
else
{
console.log("O turn")
const randomValue = Math.floor(Math.random() * 10);
autoClick[randomValue].current.click()
}
const newBoard = board
newBoard[currPosition-1] = symbol
const finalBoard = newBoard
setBoard(finalBoard);
setGame(isWinner(finalBoard, symbol));
setTie(catScratch(board))
})
字符串
2条答案
按热度按时间ruoxqz4g1#
autoClick
在组件体中是一个初始化的空数组,不会触发重新呈现。这导致useEffect
中的未定义引用。尝试:
字符串
yc0p9oo02#
在React中,一切都由state / props控制。而不是模拟单击,只需通过调用
handlePlayersTurn(position)
直接更改状态。另外,你有太多的状态。如果你需要从
playerMove
中得到一个值(例如symbol
),你不需要一个不同的状态,只需要在运行中计算它。备注:这个例子不包括获胜/平局条件。2当没有更多的单元格时,
useEffect
将被跳过。3另外,只有打开的单元格才会有点击处理程序。