reactjs - 如何编写一个依赖于反应道具的计时器间隔?
问题描述
我正在为我的网站创建一个简单的弹出窗口组件,并且我想定期收集大约每秒左右的任何新消息或传入消息,以实现实时消息传递功能。我目前正在为我的项目使用 react。
我的主要问题是,我只想在名为“active”的道具设置为 True 时收集消息,但我不知道该怎么做。
这是我的网页模型,希望能有所帮助。它是网页的模型,包含三个条目,其中一个带有打开的消息窗口。
我有多个条目可以打开它们的消息窗口,但我已经传递了其他道具,因此一次只能打开一个消息窗口。因此,可以在组件的祖先之一中使用间隔/计时器,但我想通过自己调用 API 来使这个弹出窗口更加自给自足。
我尝试使用 setInterval 函数,该函数在消息窗口组件内的 useEffect 函数中进行初始化:
let my_interval = useRef() // ???? Don't think this is the solution
const timerHandler = useCallback(() => {
// Some call to my RestAPI here.
console.log("Timer called")
}, active)
// If the "active" prop turns true, the interval should be running. Else, clear the interval if it exists.
// Here, the trouble is the interval handle "my_interval" is changing so I can't clear the original interval.
useEffect(() => {
if (active) my_interval = setInterval(timerHandler, 1000);
else if (!active) clearInterval(my_interval)
}, [active])
但是,正如评论指出的那样,我实际上无法清除间隔,因为我找不到使间隔句柄 my_interval 足够稳定的方法(useRef 不起作用)
我还尝试使用带有递归调用的超时函数,只要 active 为真,它就会继续调用自己,但我认为我有一个类似的问题,因为函数本身正在改变,所以递归调用有点坏了。
// Only do action when active is set to true. This doesn't work, when active changes to false the timer still runs.
const timeoutHandler = useCallback(() => {
if (active) console.log("Timer called")
setTimeout(timeoutHandler, 1000);
}, [active])
// Set a timeout on render, regardless of "active"
useEffect(() => {
setTimeout(timeoutHandler, 1000);
}, [])
任何帮助或不同的策略将不胜感激,我真的希望我的信使弹出窗口能够自给自足,它自己调用我的 RestAPI,但在这一点上似乎几乎不可能。
解决方案
useRef
是一个对象,请参阅其 API 文档:
const intervalRef = useRef();
// handle on active state change
useEffect(() => {
if (active) {
intervalRef.current = setInterval(() => {
console.log("Timer called");
}, 1000);
} else {
clearInterval(intervalRef.current);
}
}, [active]);
// handle unmount
useEffect(() => {
const intervalId = intervalRef.current;
return () => {
clearInterval(intervalId);
};
}, []);
推荐阅读
- r - 在 R 中安装 Caret 包时出现错误消息“系统找不到指定的路径”
- assembly - 指令流水线 - 存储/加载行为如何?
- node.js - Nodejs apis 待处理并在 7 秒后响应
- ubuntu - 如何将 certbot 添加到另一个端口
- c# - Rijndael 加密器:获取空字节 []。不加密任何东西
- sql - 分组比较
- vb.net - 收到此错误:“从字符串“”到类型“双”的转换无效。” 视觉工作室
- delphi - 在 Delphi 中如何使框架与它所在的表单完全重叠(鉴于表单可以滚动)?
- python - AttributeError:“SparseCategoricalCrossentropy”对象没有属性“_id”
- python - 使用 Python webbrowser 访问内部 chrome 页面