UseEffect 多次重新渲染
UseEffect multiple re-renders
我正在尝试做一个战舰游戏,这是我生成计算机舰船的逻辑:
const ComputerBoard = ({ COLUMNS, ROWS }) => {
const [layout, setLayout] = useState(new Array(ROWS * COLUMNS).fill('empty'));
const newLayout = [...layout];
useEffect(() => {
const checkIfShipFits = (isHorizontal, spaces, i) => {
let temp = 0;
const x = i % ROWS;
const y = Math.floor(i / COLUMNS);
for (let n = 0; n < spaces; n += 1) {
if (isHorizontal) {
if (x + spaces < COLUMNS && newLayout[i + n] !== 'ship') {
temp += 1;
}
}
if (!isHorizontal) {
if (y + spaces < ROWS && newLayout[i + COLUMNS * n] !== 'ship') {
temp += 1;
}
}
}
return temp === spaces;
};
const generateComputerLayout = () => {
const totalShips = computerShipsAvaibles;
const boardSize = ROWS * COLUMNS;
// Iterate over all types of ships
for (let j = 0; j < totalShips.length; j += 1) {
// Iterate over the amount of the specific ship
for (let k = 0; k < totalShips[j].amount; k += 1) {
let i = generateRandomIndex(boardSize);
const isHorizontal = generateRandomDirection();
while (!checkIfShipFits(isHorizontal, totalShips[j].spaces, i)) {
i = generateRandomIndex(boardSize);
}
for (let l = 0; l < totalShips[j].spaces; l += 1) {
if (isHorizontal) newLayout[i + l] = 'ship';
if (!isHorizontal) newLayout[i + COLUMNS * l] = 'ship';
}
}
}
setLayout(newLayout);
};
generateComputerLayout();
}, [COLUMNS, ROWS]);
Math.floor(Math.random() * (COLUMNS * ROWS));
return (
<div>
<h3>Computer</h3>
<div className='board'>
{layout.map((square, index) => (
<div
// eslint-disable-next-line react/no-array-index-key
key={index}
className={`square ${square} computer`}
/>
))}
</div>
</div>
);
};
目前它正在运行,但在开发者控制台中抛出警告:
React Hook useEffect has a missing dependency: 'newLayout'. Either include it or remove the dependency array react-hooks/exhaustive-deps
当我将 newLayout 变量添加到依赖项数组时,应用程序因 useEffect 多次重新呈现而崩溃。我该如何解决这个错误?也许我用错了 useEffect.
您的效果取决于状态变量的先前值,因此您可以执行以下操作,而不是将其作为依赖项:
const ComputerBoard = ({ COLUMNS, ROWS }) => {
const [layout, setLayout] = useState(new Array(ROWS * COLUMNS).fill('empty'));
useEffect(() => {
setLayout((previousLayout) => {
const newLayout = [...previousLayout];
...
return newLayout;
}
}, [COLUMNS, ROWS]);
...
当您希望下一个状态值依赖于前一个状态时,您应该使用“功能更新”,您可以在 the React documentation.
上了解更多信息
我正在尝试做一个战舰游戏,这是我生成计算机舰船的逻辑:
const ComputerBoard = ({ COLUMNS, ROWS }) => {
const [layout, setLayout] = useState(new Array(ROWS * COLUMNS).fill('empty'));
const newLayout = [...layout];
useEffect(() => {
const checkIfShipFits = (isHorizontal, spaces, i) => {
let temp = 0;
const x = i % ROWS;
const y = Math.floor(i / COLUMNS);
for (let n = 0; n < spaces; n += 1) {
if (isHorizontal) {
if (x + spaces < COLUMNS && newLayout[i + n] !== 'ship') {
temp += 1;
}
}
if (!isHorizontal) {
if (y + spaces < ROWS && newLayout[i + COLUMNS * n] !== 'ship') {
temp += 1;
}
}
}
return temp === spaces;
};
const generateComputerLayout = () => {
const totalShips = computerShipsAvaibles;
const boardSize = ROWS * COLUMNS;
// Iterate over all types of ships
for (let j = 0; j < totalShips.length; j += 1) {
// Iterate over the amount of the specific ship
for (let k = 0; k < totalShips[j].amount; k += 1) {
let i = generateRandomIndex(boardSize);
const isHorizontal = generateRandomDirection();
while (!checkIfShipFits(isHorizontal, totalShips[j].spaces, i)) {
i = generateRandomIndex(boardSize);
}
for (let l = 0; l < totalShips[j].spaces; l += 1) {
if (isHorizontal) newLayout[i + l] = 'ship';
if (!isHorizontal) newLayout[i + COLUMNS * l] = 'ship';
}
}
}
setLayout(newLayout);
};
generateComputerLayout();
}, [COLUMNS, ROWS]);
Math.floor(Math.random() * (COLUMNS * ROWS));
return (
<div>
<h3>Computer</h3>
<div className='board'>
{layout.map((square, index) => (
<div
// eslint-disable-next-line react/no-array-index-key
key={index}
className={`square ${square} computer`}
/>
))}
</div>
</div>
);
};
目前它正在运行,但在开发者控制台中抛出警告:
React Hook useEffect has a missing dependency: 'newLayout'. Either include it or remove the dependency array react-hooks/exhaustive-deps
当我将 newLayout 变量添加到依赖项数组时,应用程序因 useEffect 多次重新呈现而崩溃。我该如何解决这个错误?也许我用错了 useEffect.
您的效果取决于状态变量的先前值,因此您可以执行以下操作,而不是将其作为依赖项:
const ComputerBoard = ({ COLUMNS, ROWS }) => {
const [layout, setLayout] = useState(new Array(ROWS * COLUMNS).fill('empty'));
useEffect(() => {
setLayout((previousLayout) => {
const newLayout = [...previousLayout];
...
return newLayout;
}
}, [COLUMNS, ROWS]);
...
当您希望下一个状态值依赖于前一个状态时,您应该使用“功能更新”,您可以在 the React documentation.
上了解更多信息