为什么这段使用 useState() 的代码不能按预期工作?



我指的是最后一行for循环中useEffect中的代码片段。在我运行代码一次之后,我控制了。用我渲染的按钮记录网格状态,我将得到一个只有数字196的数组。

import { useState, useEffect } from "react";
const Gameboard = () => {
const [grids, setGrids] = useState([]);

useEffect(() => {
setGrids([]);
for (let i = 0; i < 196; i++) {
const grid = i + 1;
setGrids([...grids, grid]);
}
}, [])
return (
<div className="game-board">
<button onClick={() => console.log(grids)}>click</button>
{grids.map(grid => (
<div key={ grid }></div>
))}
</div>
);
}

export default Gameboard;

现在我知道如何解决这个问题了:

import { useState, useEffect } from "react";
const Gameboard = () => {
const [grids, setGrids] = useState([]);

useEffect(() => {
setGrids([]);
for (let i = 0; i < 196; i++) {
const grid = i + 1;
setGrids(grids => [...grids, grid]);
}
}, [])

return (
<div className="game-board">
{grids.map(grid => (
<div key={ grid }></div>
))}
</div>
);
}

export default Gameboard;

所以后一个是有效的。这是明确的。但为什么呢?谁能给我解释一下这是怎么回事?

setGrids([…网格,网格]);

:

setGrids(网格=比;[…网格,网格]);

工作吗?为什么最后一种会得到好的结果,而另一种则不同。提前感谢!

避免在setter函数中使用状态变量。通常的做法是使用一个名为prevState的变量(或者其他的东西,但是prevState经常在这种情况下使用)。

setGrids(prevState => [...prevState, grid])
所以你的代码看起来像这样:
useEffect(() => {
// setGrids([]); // Don't need this because is already initialized to []
for (let i = 0; i < 196; i++) {
const grid = i + 1;
setGrids(prevState => [...prevState, grid]);
}
}, [])

或者可以试试这个:

useEffect(() => {
const temp = [];
for (let i = 0; i < 196; i++) {
const grid = i + 1;
temp.push(grid);
}
setGrid(temp);
}, [])

所以你只在循环结束时设置一次状态,避免不必要的重新渲染。但这取决于你的用例。

setGrids(…网格,网格]);这个的值是state但需要重新渲染以获得state的新值

例如,你第一次用新值调用setGrids(),组件还没有重新渲染,所以你的grid值还没有改变但是通过这种方式setGrids(grids =>[…网格,网格]);你告诉setter函数使用grid的值即使它没有被重新渲染

最新更新