如何改进React useOnline Hook?需规避请求与navigator.onLine
首先先修复原代码里的内存泄漏问题:原useEffect中的清理函数没有通过return导出,组件卸载时无法移除事件监听器,修正后应为:
useEffect(() => { window.addEventListener("online", handleChange); window.addEventListener("offline", handleChange); // 必须return清理函数 return () => { window.removeEventListener("online", handleChange); window.removeEventListener("offline", handleChange); }; }, []);
针对你提出的「禁用navigator.onLine、不发起网络请求」需求,推荐使用Network Information API实现,该API通过浏览器直接读取设备网络连接状态,无需发送任何请求,也完全不依赖navigator.onLine。
优化后的完整实现
import { useState, useEffect } from 'react'; export const useOnline = () => { // 初始化状态:优先用Network API判断,不支持则默认在线 const [isOnline, setIsOnline] = useState(() => { const networkConnection = navigator.connection; // 浏览器不支持API,或连接类型不是"none",则视为在线 return !networkConnection || networkConnection.type !== 'none'; }); // 监听网络连接状态变化 const handleNetworkChange = () => { const networkConnection = navigator.connection; setIsOnline(!networkConnection || networkConnection.type !== 'none'); }; useEffect(() => { const networkConnection = navigator.connection; // 不支持Network API时直接返回,保持默认状态 if (!networkConnection) return; networkConnection.addEventListener('change', handleNetworkChange); // 组件卸载时移除监听器 return () => { networkConnection.removeEventListener('change', handleNetworkChange); }; }, []); return isOnline; };
方案说明
- 核心逻辑:通过
navigator.connection获取设备网络连接信息,当connection.type为"none"时判定为离线;不支持该API的浏览器默认视为在线(可根据需求调整默认值)。 - 无网络请求:所有状态判断均通过浏览器内置API完成,不会产生任何网络流量。
- 完全脱离navigator.onLine:彻底摒弃了原实现对
navigator.onLine及online/offline事件的依赖。 - 兼容性:支持Chrome、Firefox、Edge(79+)、Safari(15.4+)等现代浏览器;旧浏览器会自动降级为默认状态。
内容的提问来源于stack exchange,提问作者elsa
相关产品推荐
相关产品推荐

