如何在RTK中设置24小时轮询?无需组件挂载时立即获取数据
实现每24小时轮询通知数据的方案
你的思路是对的,用RTK Query的lazy query配合setInterval完全可以实现需求,而且是比较合理的方案。下面是具体的实现代码和说明:
完整代码示例
import { useEffect, useState } from 'react'; import { useLazyGetUserNotificationsQuery } from "../../../../api_v2/notifications"; const NotificationComponent = () => { const [unreadedNotifications, setUnreadedNotifications] = useState([]); // 使用lazy query,不会自动发起请求 const [fetchNotifications, { data: userNotifications }] = useLazyGetUserNotificationsQuery(); useEffect(() => { // 处理请求返回的数据,更新未读通知 if (userNotifications) { const unreadedNots = userNotifications.filter(notif => !notif.read); setUnreadedNotifications(unreadedNots); } }, [userNotifications]); useEffect(() => { // 设置每24小时(86400000毫秒)执行一次请求 const intervalId = setInterval(() => { fetchNotifications(); }, 24 * 60 * 60 * 1000); // 24小时的毫秒数 // 组件卸载时清除定时器,防止内存泄漏 return () => clearInterval(intervalId); }, [fetchNotifications]); // 你的组件渲染逻辑... return ( <div> {/* 显示未读通知数量或其他内容 */} <span>未读通知:{unreadedNotifications.length}</span> </div> ); }; export default NotificationComponent;
关键细节说明
- 使用lazy query:
useLazyGetUserNotificationsQuery返回一个触发函数fetchNotifications,只有调用它才会发起API请求,完美满足「组件挂载时不立即获取数据」的要求。 - 定时器设置:
setInterval的间隔设为24小时对应的毫秒数(24*60*60*1000),确保每24小时自动刷新一次数据。 - 清理定时器:在
useEffect的返回函数中调用clearInterval,避免组件卸载后定时器仍在运行导致内存泄漏。 - 数据处理逻辑:保持你原来的过滤未读通知的逻辑,在
userNotifications更新时同步更新未读数量。
可选优化:页面刷新后保持计时
如果希望页面刷新后,继续按照之前的时间间隔触发请求(而不是从刷新时刻重新开始24小时倒计时),可以用localStorage记录上次请求的时间:
useEffect(() => { const getNextFetchDelay = () => { const lastFetchTime = localStorage.getItem('lastNotificationFetchTime'); if (lastFetchTime) { const timeDiff = Date.now() - parseInt(lastFetchTime); // 如果距离上次请求已经超过24小时,立即发起一次请求,否则计算剩余时间 return timeDiff >= 24 * 60 * 60 * 1000 ? 0 : 24 * 60 * 60 * 1000 - timeDiff; } // 第一次加载时,延迟24小时再发起请求 return 24 * 60 * 60 * 1000; }; const delay = getNextFetchDelay(); const timeoutId = setTimeout(() => { // 第一次请求后,设置循环定时器 const intervalId = setInterval(() => { fetchNotifications(); localStorage.setItem('lastNotificationFetchTime', Date.now().toString()); }, 24 * 60 * 60 * 1000); // 立即发起第一次请求(如果延迟为0的话) fetchNotifications(); localStorage.setItem('lastNotificationFetchTime', Date.now().toString()); return () => clearInterval(intervalId); }, delay); return () => clearTimeout(timeoutId); }, [fetchNotifications]);
这个优化可以保证用户在页面刷新后,不会重置24小时的轮询周期,体验更连贯。
内容的提问来源于stack exchange,提问作者David Abramov
相关产品推荐
相关产品推荐

