使用 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 设置状态的问题的主要内容,如果未能解决你的问题,请参考以下文章