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

发布: (2026年3月14日 GMT+8 12:35)
8 分钟阅读
原文: Dev.to

Source: Dev.to

现代浏览器内置了强大的 API,例如地理位置、剪贴板访问、全屏模式、网络状态等。直接在 React 中使用它们比预期更困难。你需要防范服务器端渲染,添加和移除事件监听器,处理权限,并在组件卸载时进行清理。若将这些工作乘以应用所涉及的每个浏览器 API,就会产生大量重复且易出错的代码。

ReactUse 通过提供 100+ 个 Hook 的库来解决这些问题,这些 Hook 将浏览器 API 包装成简洁、SSR 安全、TypeScript 友好的接口。下面列出的每个 Hook 在访问任何 API 之前都会检查浏览器是否可用,因此可以直接在 Next.js、Remix 以及其他 SSR 框架中使用。只需一次安装,然后按需导入:

npm i @reactuses/core

1. useMediaQuery – 响应式设计

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

import { useMediaQuery } from "@reactuses/core";

function App() {
  const isMobile = useMediaQuery("(max-width: 768px)");
  return {isMobile ?  : };
}

可使用它根据屏幕尺寸有条件地渲染布局、加载不同资源,或切换功能,而无需仅依赖 CSS。

2. useClipboard – 复制到剪贴板

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

import { useClipboard } from "@reactuses/core";

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

3. useGeolocation – 用户位置

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

import { useGeolocation } from "@reactuses/core";

function LocationDisplay() {
  const { coordinates, error, isSupported } = useGeolocation();

  if (!isSupported) return 
Geolocation is not supported.
;
  if (error) return 
Error: {error.message}
;

  return (
    
      Lat: {coordinates.latitude}, Lng: {coordinates.longitude}
    
  );
}

4. useFullscreen – 全屏模式

在任意元素上切换全屏。该 Hook 包装了 Fullscreen API,并返回当前状态以及控制函数。

import { useRef } from "react";
import { useFullscreen } from "@reactuses/core";

function VideoPlayer() {
  const ref = useRef(null);
  const [isFullscreen, { enterFullscreen, exitFullscreen, toggleFullscreen }] =
    useFullscreen(ref);

  return (
    
      
      
        {isFullscreen ? "Exit" : "Fullscreen"}
      
    
  );
}

5. useNetwork – 在线/离线 状态

监控用户的网络连接。该 Hook 跟踪在线/离线状态,并在可用时提供连接细节,如 effectiveTypedownlink

import { useNetwork } from "@reactuses/core";

function NetworkBanner() {
  const { online, effectiveType } = useNetwork();

  if (!online) return You are offline;

  return Connection: {effectiveType};
}

6. useIdle – 空闲检测

检测用户何时停止与页面交互。该 Hook 监听鼠标、键盘、触摸和可见性事件,并在指定的超时时间后返回 true

import { useIdle } from "@reactuses/core";

function IdleWarning() {
  const isIdle = useIdle(300_000); // 5 minutes
  return isIdle ? Are you still there? : null;
}

7. useDarkMode – 暗模式切换

使用系统偏好检测、localStorage 持久化,并在根元素上自动切换类来管理暗模式。

import { useDarkMode } from "@reactuses/core";

function ThemeToggle() {
  const [isDark, toggle] = useDarkMode({
    classNameDark: "dark",
    classNameLight: "light",
  });

  return (
    
      {isDark ? "Switch to Light" : "Switch to Dark"}
    
  );
}

8. usePermission – 权限状态

查询浏览器权限(地理位置、摄像头、麦克风、通知等)的状态,并实时响应变化。

import { usePermission } from "@reactuses/core";

function CameraAccess() {
  const status = usePermission("camera");

  if (status === "denied") return 
Camera access was denied.
;
  if (status === "prompt") return 
We need camera permission.
;

  return 
Camera access granted.
;
}

9. useLocalStorage – 持久化状态

useLocalStorageuseState 的直接替代实现,能够将状态持久化到 localStorage。它负责序列化、SSR 安全、通过 storage 事件实现跨标签页同步,以及错误恢复。

import { useLocalStorage } from "@reactuses/core";

function Settings() {
  const [lang, setLang] = useLocalStorage("language", "en");

  return (
     setLang(e.target.value)}>
      English
      Spanish
      French
    
  );
}

10. useEventListener – 事件处理

以声明式方式附加事件监听器,并自动进行清理,兼容 SSR。

import { useEventListener } from "@reactuses/core";

function ResizeLogger() {
  useEventListener("resize", () => {
    console.log("Window resized to", window.innerWidth, "x", window.innerHeight);
  });

  return null;
}

这些 Hook(以及更多其他 Hook)让你能够以 干净、可复用且类型安全 的方式使用浏览器 API——无需通常伴随的样板代码。祝编码愉快!

useEventListener 钩子

一个钩子,用于将事件监听器附加到任意目标(window、document 或特定元素),并具备自动清理以及 TypeScript 安全的事件类型。

import { useEventListener } from "@reactuses/core";

function KeyLogger() {
  useEventListener("keydown", (event) => {
    console.log("Key pressed:", event.key);
  });
  return 
Press any key…
;
}

Enter fullscreen mode
退出全屏模式

This is the foundational hook that many other hooks in ReactUse are built on. It avoids stale closures by always referencing the latest handler.

手动实现 vs. ReactUse

ConcernManual ImplementationReactUse Hook
SSR safety checkstypeof window !== "undefined" guards everywhereBuilt‑in
Event listener cleanupuseEffect return with removeEventListenerAutomatic
TypeScript event typesManual generic constraints per eventFully typed
Permission handlingnavigator.permissions.query + state managementSingle call
localStorage serializationJSON.parse / JSON.stringify + error handlingAutomatic
Cross‑tab syncManual storage event listenerBuilt‑in

对于单个 Hook,节省的代码量有限。但在整个应用中使用五个或更多浏览器 API 时,ReactUse 可以消除数百行防御性代码。

常见问题

这些 Hook 是否支持 SSR?

是的。ReactUse 中的每个 Hook 在访问任何 API 之前都会检查浏览器是否可用。在服务器端渲染期间,Hook 会返回安全的默认值并跳过仅浏览器的逻辑。

我可以摇树去除未使用的 Hook 吗?

是的。从 @reactuses/core 导入支持摇树。你的打包工具只会包含你实际导入的 Hook。

这些 Hook 能在 React 18 和 19 中使用吗?

ReactUse 支持 React 16.8 及以上版本。所有 Hook 与 React 18 的并发特性以及 React 19 兼容。

ReactUse 为 React 提供了 100+ 个 Hook。浏览全部 →

0 浏览
Back to Blog

相关文章

阅读更多 »