Javascript 在setInterval循环中使用setter函数时,clearInterval不起作用

Javascript 在setInterval循环中使用setter函数时,clearInterval不起作用,javascript,reactjs,setinterval,use-state,Javascript,Reactjs,Setinterval,Use State,基本上,我试着制作一个计数器,当我按下开始按钮时开始计算秒数,当我按下停止按钮时停止计数,并将其存储在秒中 当我按下开始按钮时,一个handleStart函数被触发,它将开始变量设置为1。此外,setInterval开始(每秒)重复setter函数,该函数将秒增加一。这个setInterval还有一个条件语句,当start变为0时,它会清除setInterval 当我按下停止按钮时,另一个功能handleStop会被触发,设置start为0。如果正在运行setInterval,它应该看到star

基本上,我试着制作一个计数器,当我按下开始按钮时开始计算秒数,当我按下停止按钮时停止计数,并将其存储在秒中

当我按下开始按钮时,一个handleStart函数被触发,它将开始变量设置为1。此外,setInterval开始(每秒)重复setter函数,该函数将秒增加一。这个setInterval还有一个条件语句,当start变为0时,它会清除setInterval

当我按下停止按钮时,另一个功能handleStop会被触发,设置start为0。如果正在运行setInterval,它应该看到start现在为0,并且应该清除setInterval,它应该停止更新sec变量/状态。但这是行不通的。当我记录开始时,它仍然是1,即使在按下停止变量后也是如此。如果我在handleStop函数中记录start,它会记录为0,但这不会反映在handleStart函数的进一步日志语句中。 另外,当我注释掉handleStart函数中的
setSec((prev)=>{return prev+1})
行时,一切都正常(setInterval在按下stop按钮后被清除),所以我猜useState功能有些地方我不明白。 有人能告诉我怎么了吗


export default function Bug() {
    let start = 0
    let [sec, setSec] = useState(0)
    let repeat

    function handleStart() {
        start = 1
        repeat = setInterval(() => {
            setSec((prev) => { return prev + 1 })
            console.log(start);
            if (start === 0) {
                clearInterval(repeat)
            }
        }, 100);
    }

    function handleStop() {
        start = 0
        //clearInterval(repeat) //this clearInterval is not working either
    }

    return (
        <div>
            <p>{sec}</p>
            <button onClick={handleStart}>Start</button>
            <button onClick={handleStop}>Stop</button>
        </div>
    )
}

导出默认函数Bug(){
让我们开始=0
let[sec,setSec]=useState(0)
让我重复一遍
函数handleStart(){
开始=1
重复=设置间隔(()=>{
setSec((prev)=>{return prev+1})
console.log(启动);
如果(开始==0){
清除间隔(重复)
}
}, 100);
}
函数handleStop(){
开始=0
//clearInterval(repeat)//此clearInterval也不工作
}
返回(
{sec}

开始 停止 ) }

对不起,如果这样的问题已经在这里得到了回答。我试图搜索一个类似的问题,但找不到。

您的
repeat
变量在渲染之间不存在,因此每次调用
setSec
时,它都会重新渲染

一种选择是使用与计时器变量相同的想法来存储repeat变量

constbug=()=>{
常数[sec,setSec]=useState(0)
const[repeat,setRepeat]=useState()
常量handleStart=()=>{
设置重复(设置间隔(()=>{
setSec((prev)=>{return prev+1})
}, 1000));
}
常量handleStop=()=>{
清除间隔(重复)
}
返回(
{sec}

开始 停止 ) } ReactDOM.render(,document.getElementById(“根”))

var{useReducer,useffect,useState,useRef,useCallback}=React

如果在
handleStop
中清除间隔,为什么需要清除
setInterval
的回调中的间隔。我没有注释其中一个。但是,所有的clearInterval都不起作用。
repeat
会在每次渲染时重新初始化,因此在第一次勾选之后,不再保留对间隔的引用。如果要以这种方式处理计时器,请使用Ref,在回调中清除它,或使用渲染生命周期来管理计时器的状态。将
let repeat
移动到函数外部的位置component@devnull69,这不是一个好建议。组件应该包含相关的逻辑,我认为ref在这里更合适