有人可以尝试给我有关该主题的答案吗?
如果我尝试以正确的方式进行间隔(清理和一切)
const [count,setCount] = useState(0)
useEffect(() => {
const interval = useInterval(() => setCount((count) => count + 1),1000);
() => clearInterval(interval)
},[])
我知道我不能放:
const interval = useInterval(() => setCount(count + 1),1000);
我必须使用
(count) => count + 1
,以前的值,但这是为什么呢?我不能全神贯注吗?
如果我的计数是
count = 0
如果我不使用 prevState,为什么它总是循环到 1 ...setCount(count + 1
所以一旦它到达 1 ,重新渲染然后状态为 1 所以间隔可以再次添加 +1 。
您传递给
useInterval
(或渲染中定义的任何闭包)的函数将始终“看到”它在其中定义的渲染中的状态。当您调用状态设置器时,该值也不会立即改变,这发生在刚刚被触发的下一个渲染上。当您创建该函数时,您(不知不觉地,但这只是 JS 语义)将该函数绑定到 count 的当前值,该值恰好在该函数首次定义时就在那里。记忆中的某个地方,
你可能想知道为什么在其他地方你不这样做而且没关系,这可能是因为 setter 是在一个函数中调用的,这个函数也在渲染器上重新创建,所以它避免了技术上的需要它(尽管你应该总是这样做如果它源自价值以防止陷入困境)。发生这种情况时,来自先前渲染的旧函数将被装箱并替换为绑定到新范围的新函数。
但是在这里,这个效果只被注册了一次,这将是在组件第一次加载时。现在
() => setCount(count + 1)
在词法上绑定到初始渲染中的 count
值。那是0
,所以它每次都评估为0 + 1 = 1
。在第一个渲染中,在浏览器内存深处的某处存储了 () => setCount(count + 1)
并硬连接到静态计数值。
为了解决这个问题,React 可以接受您概述的回调模式。在 React 内部,它传递给它最新的值,因此定义函数的渲染变得无关紧要。