我正在开发一款游戏,当玩家点击游戏板上的有效动作时,我需要增加一个状态变量。验证移动和进行移动的功能已全部到位;但是,我目前无法通过使用相应的钩子来增加状态变量。
我一直在使用与状态挂钩的 React 文档中定义的相同的方法来增加变量:https://reactjs.org/docs/hooks-state.html
我在这里初始化状态变量:
const [placedShips, setPlacedShips] = useState(0);
接下来,对游戏板中的每个单元格应用点击事件侦听器:
const setGameboardUp = () => {
const gameboardArray = Array.from(document.querySelectorAll(".cell"));
gameboardArray.forEach((cell) => {
cell.addEventListener("click", (e) => {
e.stopImmediatePropagation();
let direction = currentShip().direction;
let start = parseInt(cell.id);
let end = start + currentShip().length - 1;
if (playerGameboard.checkValidCoordinates(direction, start, end)) {
playerGameboard.placeShip(placedShips, direction, start, end);
console.log(placedShips + 1)
setPlacedShips(placedShips + 1);
console.log(placedShips)
}
});
不幸的是,“placedShips”状态变量仍为 0,因此我的游戏无法正常运行。我已经尝试使用以下函数,它仍然是 0:
setPlacedShips(1);
我有点不明白为什么会发生这种情况,并且在尝试其他几个修复程序时没有任何运气。作为参考,以下是我正在使用的完整组件:
let playerGameboard = gameboardFactory();
const GameboardSetup = () => {
const [humanSetupGrid, setHumanSetupGrid] = useState([]);
const [ships,_setShips] = useState([
{
name: 'carrier',
length: 5,
direction: 'horizontal'
},
{
name: 'battleship',
length: 4,
direction: 'horizontal'
},
{
name: 'cruiser',
length: 3,
direction: 'horizontal'
},
{
name: 'submarine',
length: 3,
direction: 'horizontal'
},
{
name: 'destroyer',
length: 2,
direction: 'horizontal'
}]);
const [placedShips, setPlacedShips] = useState(0);
const createGrid = () => {
const cells = [];
for (let i = 0; i < 100; i++) {
cells.push(0);
};
};
const createUiGrid = () => {
const cells = [];
for (let i = 0; i < 100; i++) {
cells.push(i);
}
let counter = -1;
const result = cells.map((cell) => {
counter++;
return <div className='cell' id={counter} />;
});
setHumanSetupGrid(result);
};
const setUpPlayerGrid = () => {
// createGrid('grid');
createUiGrid();
}
const currentShip = () => {
return ships[placedShips];
};
const setGameboardUp = () => {
const gameboardArray = Array.from(document.querySelectorAll(".cell"));
gameboardArray.forEach((cell) => {
cell.addEventListener("click", (e) => {
e.stopImmediatePropagation();
let direction = currentShip().direction;
let start = parseInt(cell.id);
let end = start + currentShip().length - 1;
if (playerGameboard.checkValidCoordinates(direction, start, end)) {
playerGameboard.placeShip(placedShips, direction, start, end);
console.log(placedShips + 1)
setPlacedShips(placedShips + 1);
console.log(placedShips)
}
});
cell.addEventListener("mouseover", (e) => {
e.stopImmediatePropagation();
let direction = currentShip().direction;
let start = parseInt(cell.id);
let end = start + currentShip().length - 1;
if (currentShip().direction === 'horizontal') {
const newShip = [];
if (playerGameboard.checkValidCoordinates(direction, start, end)) {
for (let i = start; i <= end; i++) {
newShip.push(i);
};
newShip.forEach((cell) => {
gameboardArray[cell].classList.add('test');
})
}
} else {
const newShip = [];
if (playerGameboard.checkValidCoordinates(direction, start, end)) {
for (let i = start; i <= end; i += 10) {
newShip.push(i);
};
newShip.forEach((cell) => {
gameboardArray[cell].classList.add('test');
})
}
}
})
cell.addEventListener("mouseleave", (e) => {
e.stopImmediatePropagation();
let direction = currentShip().direction;
let start = parseInt(cell.id);
let end = start + currentShip().length - 1;
if (currentShip().direction === 'horizontal') {
const newShip = [];
if (playerGameboard.checkValidCoordinates(direction, start, end)) {
for (let i = start; i <= end; i++) {
newShip.push(i);
};
newShip.forEach((cell) => {
gameboardArray[cell].classList.remove('test');
})
}
} else {
const newShip = [];
if (playerGameboard.checkValidCoordinates(direction, start, end)) {
for (let i = start; i <= end; i += 10) {
newShip.push(i);
};
newShip.forEach((cell) => {
gameboardArray[cell].classList.remove('test');
})
}
}
})
});
};
useEffect(() => {
setUpPlayerGrid();
// setUpComputerGrid();
}, []);
useEffect(() => {
console.log(humanSetupGrid)
}, [humanSetupGrid]);
// Re-render the component to enable event listeners to be added to generated grid
useLayoutEffect(() => {
setGameboardUp();
});
return (
<div className="setup-container">
<div className="setup-information">
<p className="setup-information__p">Add your ships!</p>
<button className="setup-information__btn">Rotate</button>
</div>
<div className="setup-grid">
<Table grid={humanSetupGrid} />
</div>
</div>
);
}
export default GameboardSetup;
如果有人对这里可能出现的问题有任何想法,我将非常感谢您的帮助!
谢谢。
答案 0 :(得分:3)
placedShips
不会立即反映您对其所做的更改。请参阅:useState set method not reflecting change immediately
如果您希望由于 useEffect
更改值而发生某些事情,您应该使用 placedShips
和 useEffect(() => {
// do something here once placedShips has changed
}, [placedShips])
作为依赖项之一:
placedShips
请注意,如果您在该 useEffect
中记录 {{1}},它将显示更新的值。