如何在react中只渲染一次内容?(详见下文)



我正在制作一个战舰游戏来学习反应。我生成并随机在船上放置5艘船,如果2艘船共享相同的网格,我想重新生成并重新放置每艘船。我主要尝试while循环,但大多数时候我得到了一个无限循环,或者一些意想不到的东西。我想问题是我不知道如何控制组件何时应该重新渲染。

这是我的代码(我删除了不必要的部分(:

const GameControl = () => {
const [playerBoard, setPlayerBoard] = useState(() => GameBoard('player'));
const [playerShipsArray, setPlayerShipsArray] = useState([]);

//setting up game
useEffect(() => {
generateShips()
}, [])
useEffect(() => {
// while(!checkTakenCells(playerShipsArray)){
//     generateShips()
// } **this is the problematic part**
}, [playerShipsArray])
placeShipsOnBoard(playerShipsArray, playerBoard)
//setting up game
function generateShips() {
let shipsArr = [];
while(shipsArr.length < 5){
for(let i = 1; i < 6; i++){
let startCoord = Math.floor(Math.random() * 100);
const ship = Ship(i, i, isVertical(), startCoord)
shipsArr.push(ship)
}
setPlayerShipsArray(shipsArr)
}

function checkTakenCells (array){
let takenCells = [];
array.forEach(ship => takenCells.push(...ship.takenCells()))
//if 2 ships share the same coordinate, the takenCells array will have the shared coordinate twice
return new Set(takenCells).size === takenCells.length //If ships are colliding, returns false
}

function placeShipsOnBoard(array, board){
for (let i = 0; i < array.length; i++){
board.placeShip(array[i], array[i].startCoord) 
}
}  

return (
<>
//looping through playerBoard to generate a 10x10 grid
</>
)
}
const GameControl = () => {
const [playerBoard, setPlayerBoard] = useState(() => GameBoard('player'));
const [playerShipsArray, setPlayerShipsArray] = useState([]);
//setting up game
useEffect(() => { generateShips() }, [])
useEffect(() => {
// while(!checkTakenCells(playerShipsArray)){
//     generateShips()
// } **this is the problematic part**
}, [playerShipsArray])
placeShipsOnBoard(playerShipsArray, playerBoard)
}

使用hooks编写代码是可以的,但请记住,每当状态发生变化时,GameControl内的所有内容都将重新运行。

这意味着placeShipsOnBoard将被一次又一次地调用:(

这可能是一些样板代码,请记住React组件不是游戏机,它不会每毫秒运行一次。它只有在发生变化时才会运行。

const GameControl = () => {
const [ships, setShips] = useState([])
useEffect(() => {
setTimeout(() => {
// for every 50ms, 
// move. the location of ships
setShips(newLocationShips)
}, 50)
}, [])
// render ships to the board
return (ships.map(ship => ())

你需要考虑一个没有变化的董事会,然后是基于某种事情而变化的船只,可能是事件或时间。

最新更新