はじめに
新しいReactプロジェクトを始めるたびに、useLocalStorageやuseDebounce、useWindowSizeといった定番のカスタムフックを一から書き直していませんか。ロジック自体はシンプルでも、SSR対応やイベントリスナーの後始末まで含めるとちょっとした手間がかかりますし、プロジェクトごとに微妙に実装がずれてしまうこともあります。
そんな「毎回車輪の再発明」から解放してくれるのが、Usehooks-Tsです。TypeScriptで書かれた汎用カスタムフック集で、必要なものだけをインポートしてすぐに使えます。この記事では、Usehooks-Tsの特徴からインストール方法、実践的な使い方までを解説します。
Usehooks-Tsとは
Usehooks-Tsは、Julien Caron氏が中心となって開発しているReact向けカスタムフックライブラリです。「DRY(Don't Repeat Yourself)」の原則に基づき、状態管理・ストレージ操作・イベント処理・DOM操作など、実務で頻繁に必要になるフックを35種類以上まとめて提供しています。GitHub上で7,800以上のスターを獲得しており、多くのプロジェクトで採用されている定番ライブラリです。
主な特徴
- 完全なTypeScript対応 - すべてのフックが型定義付きで提供され、ジェネリクスによる型推論も効きます
- ツリーシェイキング対応 - 使用するフックのみがバンドルに含まれるため、不要なコードを持ち込みません
- 依存関係が最小限 - 軽量な実装で、余計なライブラリを増やしません
- SSR対応 -
useLocalStorageなど一部のフックはサーバーサイドレンダリング環境も考慮した設計になっています - 豊富なドキュメント - 公式サイトに各フックの使用例とAPIシグネチャが整理されています
インストール
npm、yarn、pnpmのいずれでもインストール可能です。
npm install usehooks-ts
yarn add usehooks-ts
pnpm add usehooks-ts
基本的な使い方
もっともよく使われるフックの一つ、useLocalStorageを見てみましょう。値の保存・更新・削除を、useStateとほぼ同じ感覚で扱えます。
import { useLocalStorage } from 'usehooks-ts'
function Counter() {
const [count, setCount, removeCount] = useLocalStorage('count', 0)
return (
<div>
<p>現在のカウント: {count}</p>
<button onClick={() => setCount((prev) => prev + 1)}>増やす</button>
<button onClick={() => setCount(0)}>リセット</button>
<button onClick={removeCount}>保存データを削除</button>
</div>
)
}
setCountには値そのものだけでなく、useStateと同様に更新関数も渡せます。ページをリロードしても値がlocalStorageに残り続けるのがポイントです。
実践的なユースケース
ダークモード切り替え
useDarkModeを使えば、OSの設定を尊重しつつユーザー自身での切り替えにも対応したダークモードをすぐに実装できます。
import { useDarkMode } from 'usehooks-ts'
function ThemeToggle() {
const { isDarkMode, toggle } = useDarkMode()
return (
<button onClick={toggle}>
{isDarkMode ? 'ライトモードに切り替え' : 'ダークモードに切り替え'}
</button>
)
}
検索入力のデバウンス処理
入力のたびにAPIを叩いてしまうと無駄なリクエストが増えてしまいます。useDebounceCallbackを使えば、入力が落ち着いたタイミングだけ処理を実行できます。
import { useState } from 'react'
import { useDebounceCallback } from 'usehooks-ts'
function SearchBox() {
const [keyword, setKeyword] = useState('')
const debouncedSearch = useDebounceCallback((value: string) => {
console.log('検索実行:', value)
// ここで検索APIを呼び出す
}, 500)
return (
<input
type="text"
placeholder="キーワードを入力"
onChange={(e) => {
setKeyword(e.target.value)
debouncedSearch(e.target.value)
}}
value={keyword}
/>
)
}
要素の画面内表示を検知する
無限スクロールや遅延読み込みでよく使う「要素が画面内に入ったか」の判定も、useIntersectionObserverで簡単に実現できます。
import { useRef } from 'react'
import { useIntersectionObserver } from 'usehooks-ts'
function LazySection() {
const ref = useRef<HTMLDivElement>(null)
const entry = useIntersectionObserver(ref, {})
const isVisible = !!entry?.isIntersecting
return (
<div ref={ref}>
{isVisible ? '画面内に表示されました!' : '読み込み待機中...'}
</div>
)
}
まとめ
Usehooks-Tsは、Reactアプリケーション開発で「あるある」な処理を型安全なフックとしてまとめてくれる便利なライブラリです。localStorageの管理やダークモード、デバウンス処理、Intersection Observerといった定番の実装を自作する手間が省け、コードの見通しも良くなります。ツリーシェイキングにも対応しているため、必要なフックだけを取り込めばバンドルサイズを気にする必要もありません。
まずは公式ドキュメントで用意されているフックの一覧をざっと眺めてみて、自分のプロジェクトで使えそうなものから取り入れてみてはいかがでしょうか。
