beautiful-react-hooks、react-async-hook、react-query、react-use、usehooks-ts はすべてReactアプリケーションで再利用可能なロジックを提供するカスタムフック集です。これらのライブラリは非同期処理、状態管理、DOM操作、ライフサイクル制御など、日常的な開発タスクを簡素化することを目的としています。ただし、それぞれ設計思想や対象領域、成熟度が大きく異なります。例えば react-query はサーバー状態管理に特化し、データフェッチング・キャッシング・再検証を包括的に扱うのに対し、react-use や usehooks-ts は汎用的なユーティリティフック(例:useDebounce、useLocalStorage)を多数提供します。一方、beautiful-react-hooks と react-async-hook はより限定的な用途に焦点を当てており、後者は非同期操作専用の抽象化を提供します。
React開発において、カスタムフックはロジックの再利用とコンポーネントの単純化を実現する強力な手段です。しかし「どのフックライブラリを使うべきか?」という問いには、用途によって明確な答えがあります。ここでは beautiful-react-hooks、react-async-hook、react-query、react-use、usehooks-ts の5つを、実際のコードと設計思想に基づいて比較します。
react-async-hook: 最小限の非同期ラッパーreact-async-hook は useAsync という1つの主要フックで、Promiseの実行と状態管理を簡単にします。
import { useAsync } from 'react-async-hook';
function UserProfile({ userId }) {
const asyncResult = useAsync(fetchUser, [userId]);
if (asyncResult.loading) return <div>Loading...</div>;
if (asyncResult.error) return <div>Error!</div>;
return <div>{asyncResult.result.name}</div>;
}
このアプローチはシンプルですが、キャッシュや自動再検証、並列リクエストの重複排除といった機能はありません。同じユーザーIDで複数回呼び出すと、毎回ネットワークリクエストが発生します。
react-query: データフェッチのフルスタックソリューションreact-query はキーに基づいた自動キャッシュ、バックグラウンド更新、エラーハンドリング、依存クエリなどを提供します。
import { useQuery } from '@tanstack/react-query';
function UserProfile({ userId }) {
const { data, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
staleTime: 1000 * 60 * 5 // 5分間はfreshと見なす
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error!</div>;
return <div>{data.name}</div>;
}
同じ queryKey を使う限り、2回目以降はキャッシュから即座に返却され、不要なリクエストは発生しません。さらに、画面に戻ったときに自動で最新情報を取得(stale-while-revalidate)するなど、UX向上のための機能が豊富です。
beautiful-react-hooks: 非同期専用フックは提供していません。react-use: useAsync や useAsyncFn がありますが、キャッシュ機能はなく、react-async-hook と同程度のシンプルさです。usehooks-ts: 非同期専用フックは含まれていません。💡 結論: サーバーからデータを取得する必要があるなら、たとえ簡単なケースでも
react-queryを使うことを強く推奨します。将来的に要件が複雑になってもスムーズに拡張できます。
react-use: 超多機能だが型が弱いreact-use は100以上のフックを提供しており、例えば以下のようなものがあります。
import { useDebounce, useLocalStorage, useWindowSize } from 'react-use';
function MyComponent() {
const [value, setValue] = useState('');
const debouncedValue = useDebounce(value, 500);
const [storedName, setStoredName] = useLocalStorage('name', '');
const windowSize = useWindowSize();
// ...
}
ただし、TypeScriptサポートは完全ではなく、一部のフックでは型推論が効かなかったり、型定義が曖昧だったりします。また、提供されているフックの質にばらつきがあり、一部はドキュメントが不十分です。
usehooks-ts: 厳選された高品質フックusehooks-ts は人気のあるユーティリティフックをTypeScriptで再実装したもので、コード品質と型安全性に重点を置いています。
import { useDebounce, useLocalStorage, useWindowSize } from 'usehooks-ts';
function MyComponent() {
const [value, setValue] = useState('');
const debouncedValue = useDebounce(value, 500);
const [storedName, setStoredName] = useLocalStorage('name', '');
const { width, height } = useWindowSize();
// 全て完全なTypeScriptサポート
}
提供されているフックの数は react-use より少ないですが、どれも一貫性のあるAPI設計としっかりとした型定義、そして明確なドキュメントが特徴です。
beautiful-react-hooks: UIインタラクションに特化このライブラリは主にマウス、キーボード、位置情報などのDOM/ブラウザイベントを扱います。
import { useMouse, useGeolocation } from 'beautiful-react-hooks';
function InteractiveComponent() {
const mouse = useMouse();
const geo = useGeolocation();
return (
<div>
Mouse: ({mouse.x}, {mouse.y})
Location: {geo.latitude}, {geo.longitude}
</div>
);
}
ただし、公式ドキュメントが不十分で、APIが頻繁に変わる可能性があります。また、メンテナンス状況も不安定です。
beautiful-react-hooks: GitHubリポジトリの更新が滞っており、公式ドキュメントも不完全です。新しいプロジェクトでは使用を避けてください。代わりに react-use や usehooks-ts の同等機能、または自作フックを検討しましょう。react-async-hook: 非同期処理の基本的なラッパーとしては有効ですが、react-query の普及により、新規プロジェクトでの採用理由が薄れています。特にキャッシュや再検証が必要になる可能性があるなら、最初から react-query を使うべきです。react-query + usehooks-tsreact-query で統一し、フォーム入力のディバウンスやローカルストレージなどは usehooks-ts で補完。// データ取得
const { data: users } = useQuery({ queryKey: ['users'], queryFn: fetchUsers });
// フォーム制御
const [search, setSearch] = useState('');
const debouncedSearch = useDebounce(search, 300);
// ローカル設定
const [theme, setTheme] = useLocalStorage('theme', 'light');
react-useusehooks-ts 単体| 機能/ライブラリ | beautiful-react-hooks | react-async-hook | react-query | react-use | usehooks-ts |
|---|---|---|---|---|---|
| サーバー状態管理 | ❌ | △(基本のみ) | ✅(完全対応) | ❌ | ❌ |
| 汎用ユーティリティフック | △(UIイベント中心) | ❌ | ❌ | ✅(超多機能) | ✅(厳選高品質) |
| TypeScriptサポート | △ | △ | ✅ | △ | ✅ |
| ドキュメントの充実度 | ❌ | △ | ✅ | ✅ | ✅ |
| 新規プロジェクト推奨 | ❌ | △ | ✅ | ✅ | ✅ |
react-query を使ってください。これは現代のReact開発における事実上の標準です。usehooks-ts、JavaScript中心なら react-use を選ぶのが無難です。beautiful-react-hooks と react-async-hook は、特殊な事情がない限り新規プロジェクトで使うべきではありません。既存コードに使われている場合は、段階的に置き換えることを検討しましょう。これらのライブラリは互いに排他的ではなく、react-query(データ)+ usehooks-ts(ユーティリティ)という組み合わせが、多くのプロダクションアプリケーションで最適なバランスを提供します。
react-use は非常に広範な汎用フック(100種類以上)を提供し、DOMイベント、ブラウザAPI、アニメーション、フォームなど多岐にわたります。コミュニティの支持も厚く、多くのユースケースで即座に使えるソリューションを提供します。ただし、TypeScriptサポートが完全ではなく、一部のフックは型定義が弱いことがあります。JavaScript主体のプロジェクトや、多様なユーティリティフックを一つのライブラリで揃えたい場合に最適です。
usehooks-ts は useHooks.com のTypeScript実装であり、よく使われる汎用フック(例:useDebounce, useLocalStorage, useWindowSize)を厳選して提供します。型安全性が高く、コード品質とドキュメントが整っており、小〜中規模プロジェクトで信頼性の高いユーティリティフックが必要な場合に最適です。機能数は react-use より少ないですが、その分安定性と保守性に優れています。
react-query はサーバー状態管理に特化した強力なライブラリです。データのフェッチ、キャッシュ、バックグラウンド更新、エラーリトライ、依存関係解決など、本格的なアプリケーションに必要な機能を網羅しています。APIとのやり取りが中心となる中〜大規模アプリケーションでは、このライブラリを標準として採用すべきです。ローカル状態管理や汎用ユーティリティには他のライブラリと併用するのが一般的です。
react-async-hook は非同期処理をシンプルにラップするための最小限の抽象化を提供します。useAsync のような基本的なフックでローディング・エラー状態を自動管理したい場合に適しています。ただし、キャッシュや再検証、並列リクエストといった高度な機能は含まれておらず、複雑なデータフェッチング要件がある場合は react-query を選ぶべきです。
beautiful-react-hooks は主にUIインタラクションやDOM関連のフック(例:useMouse, useGeolocation)を提供しますが、公式ドキュメントが不十分でAPIが不安定な印象があります。新しいプロジェクトでは代替手段を検討し、どうしても必要な場合のみ軽量なユースケースで限定的に使用してください。大規模アプリケーションや長期保守が必要なプロジェクトには向きません。
libreact.
npm i react-use
useBattery — tracks device battery state. useGeolocation — tracks geo location state of user's device. useHover and useHoverDirty — tracks mouse hover state of some element. useHash — tracks location hash value. useIdle — tracks whether user is being inactive.useIntersection — tracks an HTML element's intersection. useKey, useKeyPress, useKeyboardJs, and useKeyPressEvent — track keys. useLocation and useSearchParam — tracks page navigation bar location state.useLongPress — tracks long press gesture of some element.useMedia — tracks state of a CSS media query. useMediaDevices — tracks state of connected hardware devices.useMotion — tracks state of device's motion sensor.useMouse and useMouseHovered — tracks state of mouse position. useMouseWheel — tracks deltaY of scrolled mouse wheel. useNetworkState — tracks the state of browser's network connection. useOrientation — tracks state of device's screen orientation.usePageLeave — triggers when mouse leaves page boundaries.useScratch — tracks mouse click-and-scrub state.useScroll — tracks an HTML element's scroll position. useScrolling — tracks whether HTML element is scrolling.useStartTyping — detects when user starts typing.useWindowScroll — tracks Window scroll position. useWindowSize — tracks Window dimensions. useMeasure and useSize — tracks an HTML element's dimensions. createBreakpoint — tracks innerWidthuseScrollbarWidth — detects browser's native scrollbars width. usePinchZoom — tracks pointer events to detect pinch zoom in and out status. useAudio — plays audio and exposes its controls. useClickAway — triggers callback when user clicks outside target area.useCss — dynamically adjusts CSS.useDrop and useDropArea — tracks file, link and copy-paste drops.useFullscreen — display an element or video full-screen. useSlider — provides slide behavior over any HTML element. useSpeech — synthesizes speech from a text string. useVibrate — provide physical feedback using the Vibration API. useVideo — plays video, tracks its state, and exposes playback controls. useRaf — re-renders component on each requestAnimationFrame.useInterval and useHarmonicIntervalFn — re-renders component on a set interval using setInterval.useSpring — interpolates number over time according to spring dynamics.useTimeout — re-renders component after a timeout.useTimeoutFn — calls given function after a timeout. useTween — re-renders component, while tweening a number from 0 to 1. useUpdate — returns a callback, which re-renders component when called.
useAsync, useAsyncFn, and useAsyncRetry — resolves an async function.useBeforeUnload — shows browser alert when user try to reload or close the page.useCookie — provides way to read, update and delete a cookie. useCopyToClipboard — copies text to clipboard.useDebounce — debounces a function. useError — error dispatcher. useFavicon — sets favicon of the page.useLocalStorage — manages a value in localStorage.useLockBodyScroll — lock scrolling of the body element.useRafLoop — calls given function inside the RAF loop.useSessionStorage — manages a value in sessionStorage.useThrottle and useThrottleFn — throttles a function. useTitle — sets title of the page.usePermission — query permission status for browser APIs.
useEffectOnce — a modified useEffect hook that only runs once.useEvent — subscribe to events.useLifecycles — calls mount and unmount callbacks.useMountedState and useUnmountPromise — track if component is mounted.usePromise — resolves promise only while component is mounted.useLogger — logs in console as component goes through life-cycles.useMount — calls mount callbacks.useUnmount — calls unmount callbacks.useUpdateEffect — run an effect only on updates.useIsomorphicLayoutEffect — useLayoutEffect that that works on server.useDeepCompareEffect, useShallowCompareEffect, and useCustomCompareEffect
createMemo — factory of memoized hooks.createReducer — factory of reducer hooks with custom middleware.createReducerContext and createStateContext — factory of hooks for a sharing state between components.useDefault — returns the default value when state is null or undefined.useGetSet — returns state getter get() instead of raw state.useGetSetState — as if useGetSet and useSetState had a baby.useLatest — returns the latest state or propsusePrevious — returns the previous state or props. usePreviousDistinct — like usePrevious but with a predicate to determine if previous should update.useObservable — tracks latest value of an Observable.useRafState — creates setState method which only updates after requestAnimationFrame. useSetState — creates setState method which works like this.setState. useStateList — circularly iterates over an array. useToggle and useBoolean — tracks state of a boolean. useCounter and useNumber — tracks state of a number. useList useUpsertuseMap — tracks state of an object. useSet — tracks state of a Set. useQueue — implements simple queue.useStateValidator — tracks state of an object. useStateWithHistory — stores previous state values and provides handles to travel through them. useMultiStateValidator — alike the useStateValidator, but tracks multiple states at a time. useMediatedState — like the regular useState but with mediation by custom function. useFirstMountState — check if current render is first. useRendersCount — count component renders. createGlobalState — cross component shared state.useMethods — neat alternative to useReducer. useEnsuredForwardedRef and ensuredForwardRef — use a React.forwardedRef safely.
Usage — how to import.
Unlicense — public domain.
Support — add yourself to backer list below.