【发布时间】:2019-10-29 04:11:21
【问题描述】:
我试图弄清楚 useEffect 何时会导致重新渲染。我对以下示例的结果感到非常惊讶:
https://codesandbox.io/embed/romantic-sun-j5i4m
function useCounter(arr = [1, 2, 3]) {
const [counter, setCount] = useState(0);
useEffect(() => {
for (const i of arr) {
setCount(i);
console.log(counter);
}
}, [arr]);
}
function App() {
useCounter();
console.log("render");
return <div className="App" />;
}
这个例子的结果如下:
我不知道为什么:
- 组件仅渲染 3 次(我猜该组件会在每次调用
setCount+ 一次初始渲染时重新渲染 - 所以 4 次) - 计数器只有两个值 0 和 3:我猜,正如 article 所指出的,每个渲染都会看到自己的状态和道具,因此整个循环将以每个状态作为常数运行(1、2、 3) --> 但是为什么状态永远不是 2?
【问题讨论】:
-
设置状态是异步的,也不会改变
counter变量的值。所以即使你调用setState(...),函数内部的counter值也会被保留。这就是为什么您在第一次运行中看到 3x0 零,然后在第二次运行中看到 3x3(最后一次调用是setCount(3)所以这就是counter将在下一次重新渲染时设置为)。 -
好的 - 我知道计数器应该是特定渲染中的常量。但是 setCount 应该异步调度。我会假设 setCount 会触发重新渲染,其中计数器是 1 然后 2 然后 3。所以,我希望输出像 3x0 然后 3x1, 3x2 ...
-
如果你这样做
setCount(1); setCount(2); setCount(3),那么在下一次重新渲染期间counter将是 3。React 不仅仅应用一个状态更新,而是所有这些更新——而且它发生了您多次覆盖相同的状态。 -
感谢您的评论。但究竟是什么导致了重新渲染?如果更改状态不会立即导致重新渲染?归根结底,react 不知道我的数组有 3 个元素,第三个元素之后需要重新渲染?
-
现在 React DevTools 中有一个实验性功能可以回答这个确切的问题 - Why did this render? - 这是你可以如何install it。
标签: reactjs react-hooks