2026年3月17日
ReactUse vs usehooks-ts:該選哪個 React Hooks 函式庫?
ReactUse(@reactuses/core)和 usehooks-ts 都是以 TypeScript 為優先的 React Hooks 函式庫,旨在減少元件中的樣板程式碼。它們有著相似的理念——提供簡潔、可複用的 Hooks 和出色的型別推斷——但在涵蓋範圍、SSR 處理和瀏覽器 API 支援方面存在顯著差異。
我們維護著 ReactUse,所以有自己的立場。但我們已盡力做到公平,承認 usehooks-ts 的優勢。
概覽比較
| 功能 | ReactUse | usehooks-ts |
|---|---|---|
| Hook 數量 | 100+ | ~30 |
| TypeScript 優先 | 是 | 是 |
| Tree-shaking | 是 | 是 |
| SSR 安全 | 是(內建 isBrowser 防護) | 各 Hook 不一 |
| 每個 Hook 體積 | 小 | 小 |
| 分類體系 | 瀏覽器、狀態、元素、感測器、動畫、副作用 | 通用 |
| 互動式範例 | 是 | 否(展示原始碼) |
| 瀏覽器 API Hooks | 地理定位、剪貼簿、全螢幕、語音、通知等 | 有限 |
| DOM 觀察者 Hooks | IntersectionObserver、ResizeObserver、MutationObserver | 僅 IntersectionObserver |
| 維護狀態 | 積極 | 積極 |
程式碼比較:useLocalStorage
ReactUse:
import { useLocalStorage } from "@reactuses/core";
function Settings() {
const [theme, setTheme] = useLocalStorage("theme", "light");
return (
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
目前: {theme}
</button>
);
}
usehooks-ts:
import { useLocalStorage } from "usehooks-ts";
function Settings() {
const [theme, setTheme] = useLocalStorage("theme", "light");
return (
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
目前: {theme}
</button>
);
}
兩者的 API 幾乎完全相同,都回傳模仿 useState 的 [value, setter] 元組。這是 usehooks-ts 最大的優點之一——API 簡潔且熟悉。
程式碼比較:useMediaQuery
ReactUse:
import { useMediaQuery } from "@reactuses/core";
function ResponsiveLayout() {
const isMobile = useMediaQuery("(max-width: 768px)");
return <div>{isMobile ? "行動裝置" : "桌面"}</div>;
}
usehooks-ts:
import { useMediaQuery } from "usehooks-ts";
function ResponsiveLayout() {
const isMobile = useMediaQuery("(max-width: 768px)");
return <div>{isMobile ? "行動裝置" : "桌面"}</div>;
}
同樣非常相似。兩個函式庫都回傳布林值。差異在 SSR 層——ReactUse 內部對 window.matchMedia 呼叫進行了防護,在伺服器端渲染時安全地回傳 false,無需你做額外處理。
程式碼比較:useDebounce
ReactUse:
import { useDebounceFn } from "@reactuses/core";
function Search() {
const { run } = useDebounceFn((query: string) => {
fetch(`/api/search?q=${query}`);
}, 300);
return <input onChange={(e) => run(e.target.value)} />;
}
usehooks-ts:
import { useDebounceCallback } from "usehooks-ts";
function Search() {
const debouncedFetch = useDebounceCallback((query: string) => {
fetch(`/api/search?q=${query}`);
}, 300);
return <input onChange={(e) => debouncedFetch(e.target.value)} />;
}
兩者都能很好地運作。ReactUse 還額外提供 useThrottleFn、useDebouncedValue 和 useThrottledValue,滿足更細粒度的控制需求。
SSR 安全性
這是兩個函式庫之間最重要的實際差異。
ReactUse 在每個存取 window、document 或 navigator 的 Hook 中內部檢查 isBrowser。你永遠不需要自己撰寫 typeof window !== "undefined"。這意味著 ReactUse 的 Hooks 在 Next.js、Remix 和任何其他 SSR 框架中開箱即用。
usehooks-ts 的 SSR 處理不夠一致。部分 Hook 做了瀏覽器 API 防護,部分沒有。如果你在建構 SSR 應用,可能需要在 usehooks-ts 的 Hook 外層加上自己的防護或使用動態匯入,這增加了複雜度。
何時選擇 usehooks-ts
usehooks-ts 在以下情境是不錯的選擇:
- 你只需要少量常用 Hooks(localStorage、media query、debounce、click outside)
- 你的專案是純用戶端 SPA,沒有 SSR 需求
- 你希望相依性體積盡可能小
- 你喜歡在文件中直接閱讀原始碼——usehooks-ts 展示了每個實作
usehooks-ts 在它的領域做得很好。實作簡潔、可讀、易理解。對於只需少量工具的小型專案,它是完全合理的選擇。
何時選擇 ReactUse
ReactUse 更適合以下情境:
- 你在建構可能現在或將來需要 SSR 的生產應用
- 你需要基礎之外的瀏覽器 API Hooks(地理定位、剪貼簿、全螢幕、語音辨識、電池狀態、通知)
- 你需要 DOM 觀察者 Hooks(IntersectionObserver、ResizeObserver、MutationObserver、元素邊界)
- 你需要動畫工具(useRafFn、useTransition、useInterval、useTimeout)
- 你需要感測器 Hooks(useDeviceMotion、useDeviceOrientation、useMouse、useScroll)
- 你希望用一個函式庫涵蓋 100+ 個使用情境,而非拼湊多個套件
遷移指南:從 usehooks-ts 遷移到 ReactUse
如果你已在使用 usehooks-ts 並想遷移,過程很簡單,因為兩個函式庫都遵循 [value, setter] 慣例。
第一步:安裝 ReactUse
npm i @reactuses/core
第二步:更新匯入
| usehooks-ts | ReactUse |
|---|---|
useLocalStorage | useLocalStorage |
useMediaQuery | useMediaQuery |
useDebounceCallback | useDebounceFn |
useIntersectionObserver | useIntersectionObserver |
useEventListener | useEventListener |
useOnClickOutside | useClickOutside |
useCopyToClipboard | useClipboard |
第三步:移除 SSR 防護程式碼 ——ReactUse 在內部處理,你可以刪除為 usehooks-ts Hooks 新增的所有 typeof window 檢查。
安裝
npm i @reactuses/core
import { useLocalStorage, useMediaQuery, useClipboard } from "@reactuses/core";
每個 Hook 都在 reactuse.com 上提供了即時範例、完整的 API 參考和 TypeScript 定義。
立即試用 ReactUse。開始使用 →