Next.js中SWR仅窗口恢复聚焦时更新,如何实现页面持续自动刷新?
解决方案
可以用SWR的refreshInterval结合页面可见性监听来实现页面聚焦时的持续自动更新,无需WebSocket。具体实现如下:
修改后的完整代码
import { useEffect, useState } from 'react'; import useSWR from 'swr'; import axios from 'axios'; // 简化fetcher函数 const fetcher = () => axios.get('/api/model').then(res => res.data); export default function Model() { // 跟踪页面可见状态,初始值为当前页面是否可见 const [isPageVisible, setIsPageVisible] = useState(document.visibilityState === 'visible'); // 监听页面可见性变化事件 useEffect(() => { const handleVisibilityChange = () => { setIsPageVisible(document.visibilityState === 'visible'); }; document.addEventListener('visibilitychange', handleVisibilityChange); // 组件卸载时移除监听 return () => document.removeEventListener('visibilitychange', handleVisibilityChange); }, []); // 配置SWR的自动刷新规则 const { data, error, isLoading } = useSWR('/api/model', fetcher, { // 页面可见时每秒刷新一次,不可见时停止自动刷新 refreshInterval: isPageVisible ? 1000 : 0, // 保留默认的聚焦时重新验证,确保切回窗口时立即更新数据 revalidateOnFocus: true, // 避免请求堆积:同一1秒内重复请求会被合并 dedupingInterval: 1000 }); // 加载状态处理 if (isLoading) return <p>加载中...</p>; if (error) return <p>数据加载失败</p>; return <p>{JSON.stringify(data)}</p>; }
核心原理
- 页面可见性监听:通过
visibilitychange事件实时获取页面是否处于聚焦可见状态,动态调整SWR的刷新间隔。 - 动态refreshInterval:当页面可见时设置为1000ms(每秒发起一次请求),页面隐藏时设为0(停止自动刷新),减少不必要的请求开销。
- 请求去重:通过
dedupingInterval确保同一时间范围内的重复请求被合并,避免接口压力过大。
内容的提问来源于stack exchange,提问作者TungTung
相关产品推荐
相关产品推荐

