setInterval内的函数在ReactJs中无法正常工作

setInterval内的函数在ReactJs中无法正常工作,reactjs,react-hooks,Reactjs,React Hooks,我看过很多关于在React中创建计时器的教程 useEffect(() => { let interval = null; if (timeractive) { interval = setInterval(() => { setCount(count => count+ 1); }, 50); } else { clearInterval(interval);

我看过很多关于在React中创建计时器的教程

  useEffect(() => {
     let interval = null;
       if (timeractive) {
         interval = setInterval(() => {
           setCount(count => count+ 1);
         }, 50);
       } else {
         clearInterval(interval);
       }
       return () => clearInterval(interval);
     },[timeractive,count]);
这就是我认为正在发生的事情:

1
timeractive=true

2调用
useffect
,声明将变量
interval
分配给
setInterval

3
setCount
被调用,递增
count

4再次调用
useffect
,因为
count
是其依赖项之一。但是前面的
useffect
中的cleanup函数首先运行,清除变量
interval

5返回到步骤2

我不想这样做,因为这看起来很不直观。它本质上是通过创建和清除一组只持续一次迭代的较小间隔来创建一个较大的“间隔”

因此,我编写了以下代码,试图创建一个不依赖于递增内容的计时器。这就是为什么我决定使用useRef,以便在渲染之间保持时间间隔

这是一个计时器,每100ms增加一个半径,并用该半径画一个圆(模50),它应该是一个动画,但不起作用。然而,半径似乎正在更新中。因此,
drawcircle
函数出现了一些问题

我问了一个类似的问题,这就是为什么我决定在
setRadius

在这种情况下,有人能解释一下闭包的概念吗

const{useState,useffect,useRef}=React;
函数计时器({active}){
const intervalRef=useRef(null);
const canvasRef=useRef(null);
常数[宽度、高度]=[500500];
const[radius,setRadius]=useState(30);
useffect(()=>{
如果(活动){
intervalRef.current=setInterval(()=>{
画圈();
设置半径(半径=>半径+1);
},100)
}否则{
清除间隔(间隔参考电流)
}
},[活动])
常量drawcircle=()=>{
const context=canvasRef.current.getContext('2d');
context.clearRect(0,0,宽度,高度)
context.beginPath()
弧(宽度/2,高度/2,半径%50,0,2*Math.PI)
stroke();
}
返回(
半径为{radius}

) } 函数Main(){ const[active,setActive]=useState(false) 返回( {setActive(!active)}}>切换 ) } ReactDOM.render(,document.getElementById('app'))
间隔回调在每次迭代时使用第一次渲染的
drawcircle
方法,该
drawcircle
方法指的是初始半径值。要解决此问题,请使用ref To
drawcircle
方法

drawcircleRef = useRef()
useEffect(()=>{
        if(active){
            drawcircleRef.current = drawcircle
            const interval= setInterval(()=>{
                drawcircleRef.current();
                setRadius(radius => radius + 1);
            },100)
           return ()=>  clearInterval(interval) 
        }
    },[active])
useEffect(()=>{
        drawcircleRef.current = drawcircle
    },[radius])