每个 React 开发者都需要的 10 个浏览器 API Hooks

学习如何在 React 中使用 Geolocation、Clipboard、Fullscreen、Media Queries 等浏览器 API,借助 ReactUse 提供的简洁、可复用的 Hooks。

原文发布于 reactuse.com

现代浏览器提供了强大的 API,包括地理定位、剪贴板访问、全屏模式、网络状态等等。在 React 中直接使用它们比应有的难度更大。你需要防范服务端渲染、添加和移除事件监听器、处理权限,以及在卸载时清理。将这些工作乘以你的应用涉及的每个浏览器 API,你就有了大量重复且容易出错的代码。

ReactUse 通过一个包含 100 多个 Hooks 的库来解决这个问题,将浏览器 API 封装为简洁的、SSR 安全的、TypeScript 友好的接口。只需安装一次,按需导入:

bash 复制代码
npm i @reactuses/core

1. useMediaQuery -- 响应式设计

在 JavaScript 中响应 CSS 媒体查询。该 Hook 返回一个布尔值,在视口变化时实时更新。

tsx 复制代码
import { useMediaQuery } from "@reactuses/core";

function App() {
  const isMobile = useMediaQuery("(max-width: 768px)");
  return <div>{isMobile ? <MobileNav /> : <DesktopNav />}</div>;
}

2. useClipboard -- 复制到剪贴板

使用现代 Clipboard API 读写系统剪贴板。该 Hook 处理权限、HTTPS 要求和焦点状态边界情况。

tsx 复制代码
import { useClipboard } from "@reactuses/core";

function CopyButton({ text }: { text: string }) {
  const [clipboardText, copy] = useClipboard();
  return (
    <button onClick={() => copy(text)}>
      {clipboardText === text ? "Copied!" : "Copy"}
    </button>
  );
}

3. useGeolocation -- 用户位置

追踪用户的地理坐标,在卸载时自动清理 watchPosition 监听器。

tsx 复制代码
import { useGeolocation } from "@reactuses/core";

function LocationDisplay() {
  const { coordinates, error, isSupported } = useGeolocation();
  if (!isSupported) return <p>不支持地理定位。</p>;
  if (error) return <p>错误: {error.message}</p>;
  return <p>纬度: {coordinates.latitude}, 经度: {coordinates.longitude}</p>;
}

4. useFullscreen -- 全屏模式

对任意元素切换全屏。该 Hook 封装了 Fullscreen API,返回当前状态和控制函数。

tsx 复制代码
import { useRef } from "react";
import { useFullscreen } from "@reactuses/core";

function VideoPlayer() {
  const ref = useRef<HTMLDivElement>(null);
  const [isFullscreen, { toggleFullscreen }] = useFullscreen(ref);
  return (
    <div ref={ref}>
      <video src="/demo.mp4" />
      <button onClick={toggleFullscreen}>
        {isFullscreen ? "退出" : "全屏"}
      </button>
    </div>
  );
}

5. useNetwork -- 在线/离线状态

监控用户的网络连接。该 Hook 追踪在线/离线状态,在可用时还提供连接详情。

tsx 复制代码
import { useNetwork } from "@reactuses/core";

function NetworkBanner() {
  const { online, effectiveType } = useNetwork();
  if (!online) return <div className="banner">您已离线</div>;
  return <div>连接类型: {effectiveType}</div>;
}

6. useIdle -- 空闲检测

检测用户何时停止与页面交互。

tsx 复制代码
import { useIdle } from "@reactuses/core";

function IdleWarning() {
  const isIdle = useIdle(300_000); // 5 分钟
  return isIdle ? <div>你还在吗?</div> : null;
}

7. useDarkMode -- 深色模式切换

管理深色模式,包含系统偏好检测、localStorage 持久化和根元素自动类名切换。

tsx 复制代码
import { useDarkMode } from "@reactuses/core";

function ThemeToggle() {
  const [isDark, toggle] = useDarkMode({
    classNameDark: "dark",
    classNameLight: "light",
  });
  return (
    <button onClick={toggle}>
      {isDark ? "切换到浅色" : "切换到深色"}
    </button>
  );
}

8. usePermission -- 权限状态

查询浏览器权限的状态并实时响应变化。

tsx 复制代码
import { usePermission } from "@reactuses/core";

function CameraAccess() {
  const status = usePermission("camera");
  if (status === "denied") return <p>摄像头访问被拒绝。</p>;
  if (status === "prompt") return <p>我们需要摄像头权限。</p>;
  return <p>摄像头访问已授权。</p>;
}

9. useLocalStorage -- 持久化状态

useState 的替代方案,持久化到 localStorage。处理序列化、SSR 安全性、跨标签页同步和错误恢复。

tsx 复制代码
import { useLocalStorage } from "@reactuses/core";

function Settings() {
  const [lang, setLang] = useLocalStorage("language", "en");
  return (
    <select value={lang ?? "en"} onChange={(e) => setLang(e.target.value)}>
      <option value="en">English</option>
      <option value="es">Spanish</option>
      <option value="fr">French</option>
    </select>
  );
}

10. useEventListener -- 事件处理

将事件监听器附加到任何目标,自动清理,并提供 TypeScript 安全的事件类型。

tsx 复制代码
import { useEventListener } from "@reactuses/core";

function KeyLogger() {
  useEventListener("keydown", (event) => {
    console.log("按键:", event.key);
  });
  return <p>按任意键...</p>;
}

手动实现 vs. ReactUse

关注点 手动实现 ReactUse Hook
SSR 安全检查 到处添加 typeof window !== "undefined" 内置
事件监听器清理 useEffect + removeEventListener 自动
TypeScript 事件类型 手动泛型约束 完全类型化
localStorage 序列化 JSON.parse/stringify + 错误处理 自动
跨标签页同步 手动 storage 事件监听 内置

对于单个 Hook 来说节省量不大。但在整个应用中使用五个或更多浏览器 API 时,ReactUse 消除了数百行防御性代码。


ReactUse 提供了 100 多个 React Hooks。查看全部 →

相关推荐
BigTopOne5 小时前
【WebRtc】DTLS-SRTP 加密完整流程详解
前端
陈随易5 小时前
pm2 替代品,nodejs&bun 线上部署必备工具
前端·后端·程序员
单线程_015 小时前
从案例分析 Vue3 Tokenizer 源码一
前端·javascript·vue.js
BigTopOne5 小时前
【WebRtc】-ICE Candidate 与 STUN/TURN 原理详解
前端
l1258655 小时前
# LangGraph Memory机制深度解析:短期记忆与长期记忆的工程实践
前端·人工智能·python·langchain·bootstrap
码视野6 小时前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
大模型码小白6 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
m0_547486666 小时前
《JavaScript核心原理 》全套PPT课件2026
开发语言·javascript·ecmascript
数智启示录7 小时前
Flink CDC 机制精讲(二):Checkpoint Barrier 如何形成一致快照 【面试宝典】
大数据·经验分享·面试·flink
xm_xm_xm_17 小时前
react17版本以前类组件常用操作
前端·javascript·react.js