使用 setInterval 和 clearInterval 设置状态的问题

Posted

技术标签:

【中文标题】使用 setInterval 和 clearInterval 设置状态的问题【英文标题】:Issue with setting State with setInterval and clearInterval 【发布时间】:2021-07-27 06:52:03 【问题描述】:

我在尝试从 setInterval() 每隔一段时间调用的函数更新状态时发现 react 的意外行为。目的是让一个按钮调用一个 setInterval,该 setInterval 调用一个从我的 mysql 数据库请求数据的函数,然后将第一个结果数组设置为我的状态。我希望同一个按钮在再次按下时也能清除间隔。一直开着。

我注意到,如果您注释掉 setData 函数,代码可以正常工作。我希望有人能解释为什么代码按预期工作,直到您尝试使用 setInterval 函数设置状态。

我猜这与没有立即更新的反应状态有关,或者甚至可能与 aysnc 有关?希望有人对正在发生的事情有更好的了解。

当前代码永远不会到达 else 块,只是设置另一个调用 getData 函数的间隔。

此代码不在 UseEffect Hook 内,该按钮具有 OnClick=toggleLive。这个按钮在 Return() 里面

const [data, setData] = useState();

const getData = async () => 
     const lastEntry = await API.getLastEntry("rig08");
     console.log(lastEntry);
     setData(lastEntry[0] || 0);
  

var dataUpdate = null;
const toggleLive = async () => 
   console.log(dataUpdate);
   if (!dataUpdate) 
      console.log("Condition");
      dataUpdate = setInterval(getData, 1000);
    else 
      console.log("Else");
      clearInterval(dataUpdate);
      dataUpdate = null;
   

return (
   <Button onClick=toggleLive className=liveBtn>Live</Button>
)

这是所有相关代码,如果需要我可以提供更多。

【问题讨论】:

这是否发生在 useEffect 挂钩中?你能分享更多代码吗 我猜你的代码永远不会去 else 块并调用 clearInterval。如果是这样,那么您需要使用 useState 来存储 dataUpdate 的值。 我已经进行了编辑以回答您的问题,您是对的,当我尝试使用 setData(lastEntry) 设置状态时,代码永远不会进入 else 块,但是当我将其注释掉时,代码按我的预期工作。 【参考方案1】:

如果不查看其余代码,很难判断,但我认为正在发生的事情是您没有正确保存间隔。调用setData 将使组件重新渲染,并且每次组件重新渲染时,dataUpdate 将被设置为null

var dataUpdate = null;

处理此问题的一种方法是将dataUpdate 间隔保存为ref -

const dataUpdateRef = React.useRef(null);
const toggleLive = async () => 
  console.log(dataUpdate);
  if (!dataUpdateRef.current) 
    console.log("Condition");
    dataUpdateRef.current = setInterval(getData, 1000);
   else 
    console.log("Else");
    clearInterval(dataUpdateRef.current);
    dataUpdateRef.current = null;
  

【讨论】:

【参考方案2】:

只是为以后可能会看到此内容的任何人做个总结,

问题是我没有正确保存间隔。我将 Gerrod 的答案与 useRef 一起使用,效果很好。祝大家好运。

【讨论】:

以上是关于使用 setInterval 和 clearInterval 设置状态的问题的主要内容,如果未能解决你的问题,请参考以下文章

jsBOM对象

js定时器

js 倒计时

js setInterval和clearInterval 的使用

setInterval的使用和停用

使用 setInterval 和 clearInterval 设置状态的问题