【发布时间】:2021-03-21 20:41:43
【问题描述】:
代码沙盒:https://codesandbox.io/s/trusting-chandrasekhar-3jpw4
我正在开发战舰游戏应用程序。在这个游戏中,用户可以点击对手的网格并选择要攻击的单元格。如果一个单元格被攻击并且它包含一艘敌舰,那么它应该有一个应用到它的类,因此会变成红色。
我遇到了一个问题,即所有功能都在工作,但在进行移动时组件没有更新。如果我进入我的组件代码做一个小改动然后保存它,我可以看到选定的单元格变成红色(如果它包含一艘敌舰)。
GameboardSetup 组件生成初始网格:
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}
onClick={onClickHandler}
onMouseOut={onMouseOutHandler}
onMouseOver={onMouseOverHandler}
/>
);
});
return result;
};
const generateAiGrid = () => {
let aiPlacedShips = 0;
let currentShipLength = null;
let currentShipDirection = null;
const generateShipDirection = () => {
let randomNumber = Math.floor(Math.random() * 2);
if (randomNumber === 0) {
return 'horizontal'
}
return 'vertical'
}
while (aiPlacedShips <= 4) {
let unavailableCells = [];
currentShipDirection = generateShipDirection();
if (aiPlacedShips === 0) {
currentShipLength = 5;
} else {
currentShipLength = ships[aiPlacedShips].length;
for (let i = 0; i < aiGameboard.shipYard.length; i++) {
aiGameboard.shipYard[i].position.forEach((val) => {
unavailableCells.push(val);
})
};
};
const generateRandom = (min, max) => {
const num = Math.floor(Math.random() * (max - min + 1)) + min;
return (unavailableCells.includes(num)) ? generateRandom(min, max) : num;
}
let currentShipStartCell = generateRandom(0, 99);
let currentShipEndCell = null;
if (currentShipDirection === 'horizontal') {
currentShipEndCell = currentShipStartCell + currentShipLength - 1;
} else {
currentShipEndCell = currentShipStartCell + ((currentShipLength - 1) * 10);
};
if ((aiGameboard.checkValidCoordinates(currentShipDirection, currentShipStartCell, currentShipEndCell)) && (!aiGameboard.checkIfShipPresent(currentShipDirection, currentShipStartCell, currentShipEndCell))) {
aiGameboard.placeShip(aiPlacedShips, currentShipDirection, currentShipStartCell, currentShipEndCell);
aiPlacedShips++;
};
};
};
然后将它们传递给 App 组件并通过以下 useEffect 函数存储在状态中:
useEffect(() => {
if (placedShips >= 5){
props.handleNextStepChange();
props.setPlayerSetupGameboard(playerGameboard);
props.setAiSetupGameboard(aiGameboard);
}
}, [placedShips]);
这些网格然后通过 props 传递给 Game 组件:
const showNextComponent = () => {
if (phase === 1) {
return (
<GameboardSetup
setPlayerSetupGameboard={setPlayerSetupGameboard}
setAiSetupGameboard={setAiSetupGameboard}
handleNextStepChange={handleNextStepChange}
/>
);
} else if (phase === 2) {
return (
<Game
playerSetupGameboard={playerSetupGameboard}
aiSetupGameboard={aiSetupGameboard}
/>
);
} else {
return (
<Intro
setPlayerName={setPlayerName}
handleNextStepChange={handleNextStepChange}
/>
);
};
};
然后将网格存储到 Game 组件中的状态中:
useEffect(() => {
setPlayerGameboard(props.playerSetupGameboard);
setAiGameboard(props.aiSetupGameboard);
}, [props]);
然后在 Game 组件中生成网格:
const createPlayerGrid = (playerGameboard) => {
if (!!playerGameboard) {
let ships = [];
let hitShips = [];
for (let i = 0; i < playerGameboard.shipYard.length; i++) {
playerGameboard.shipYard[i].position.forEach((cell) => {
ships.push(cell);
});
};
for (let i = 0; i < playerGameboard.shipYard.length; i++) {
playerGameboard.shipYard[i].hits.forEach((cell) => {
hitShips.push(cell);
});
};
const cells = [];
for (let i = 0; i < 100; i++) {
cells.push(i);
}
let counter = -1;
const result = cells.map((cell) => {
let shipStatus = '';
counter++;
if (ships.includes(counter)) {
shipStatus = 'ship';
}
if (hitShips.includes(counter)) {
shipStatus = 'hit-ship';
}
return (
<div
className={`player-cell ${shipStatus}`}
id={counter}
/>
);
});
return result;
}
};
const createAiGrid = (aiGameboard) => {
if (!!aiGameboard) {
let ships = [];
let hitShips = [];
for (let i = 0; i < aiGameboard.shipYard.length; i++) {
aiGameboard.shipYard[i].position.forEach((cell) => {
ships.push(cell);
})
}
for (let i = 0; i < aiGameboard.shipYard.length; i++) {
aiGameboard.shipYard[i].hits.forEach((cell) => {
hitShips.push(cell);
});
};
const cells = [];
for (let i = 0; i < 100; i++) {
cells.push(i);
}
let counter = -1;
const result = cells.map((cell) => {
let shipStatus = '';
counter++;
if (ships.includes(counter)) {
shipStatus = 'ship';
}
if (hitShips.includes(counter)) {
shipStatus = 'hit-ship';
}
return (
<div
className={`ai-cell ${shipStatus}`}
id={counter}
onClick={onClickHandler}
/>
);
});
return result;
}
};
这些函数的结果随后会在返回函数中呈现:
return (
<div className="main-container">
<div className="player-container">
<div className="player-grid">
<Table grid={createPlayerGrid(playerGameboard)} />
</div>
</div>
<div className="ai-container">
<div className="ai-grid">
<Table grid={createAiGrid(aiGameboard)} />
</div>
</div>
</div>
);
正如我上面提到的,如果我对 Game 组件进行了修改并在进行有效的命中移动后将其保存,则命中船类将附加到该单元格并变为红色。
我不确定为什么会发生这种情况,但我对 React 比较陌生,非常感谢任何建议。
谢谢!
【问题讨论】:
标签: reactjs