如果我在没有useEffect的情况下使用setInterval(第15行),则它给出结果2 ^ n-1(0,1,3,7,15,31,63 ...)而不是(0,1,2,3 ,4,..)。所以我有一个问题
1)为什么我直接调用不带useeffect的setInterval时得到的输出2)如果我更改setCount(line 9)并通过不使用useEffect的情况下直接使用setInterval给出正确的输出,有什么办法(就像我所做的那样)
3)如果没有useEffcet不能使用setInterval,那为什么不能呢?
如果我将setInterval放入useEffect并最初呈现一次(第12,13,14行),则比它给出正确的输出..
但是当我直接使用setInterval时,我没有得到正确的输出。 diff打赌他们是什么?
在这两种情况下,我都只调用一次setInterval,但输出为diff。
import React, {useEffect, useState } from 'react'
export default function IncorrectDependency() {
const [count,setCount]=useState(0)
const inc=()=>{
// console.log(count)
setCount(preVal=>preVal+1)
// setCount(count+1)
}
// useEffect(()=>{
// setInterval(inc,1000)},[]
// )
setInterval(inc,1000)
return (
<div>
<h1>{count}</h1>
</div>
)
}
答案 0 :(得分:3)
设置状态时,功能组件将从上到下重新执行,无论何时使用useState,useCallbacks等。它们都不会重新初始化为变量,函数,
因此,在这种情况下,setInterval
将在每个setCount
上重新初始化,因为状态已更改,
一步一步
setInterval
并会触发它,所以现在我们有了两个setIntervals
通过清除由于useEffect
导致的每次重新渲染之前的间隔,您可以在没有setCount
的情况下获得预期的结果
创建一个变量来保存设置的间隔code
const interval = null;
//this should be declare out side the component,
//because if we declare it inside the component it will redeclare,
//and the reference to the previous setInterval will be lost in that case no-way to clear the setInterval.
export default function IncorrectDependency() {
....
if (interval) {
clearInterval(interval);
}
interval = setInterval(inc, 1000);
....
}
reactor具有一个钩子,该钩子可以容纳相同的变量,而无需在每个渲染上重新初始化,将其检出useRef
这是一个code-demo
const intvl = useRef(null);
....
if (intvl?.current) {
clearInterval(intvl.current);
}
intvl.current = setInterval(inc, 1000);
.....
答案 1 :(得分:2)
当您直接使用setInterval时会发生什么情况,因为这是一个函数,它将在状态更改时被调用,因此将再次触发setInterval,依此类推,这实际上会给您不正确的结果,因此您不应在没有使用情况下使用setInterval效果,在卸下时也应清除间隔