使い方
1. ロジックをフックに切り出す
function useTimer(ms) {
const [t, setT] = React.useState(0); // 経過時間
React.useEffect(() => { // 一定間隔で +1
const id = setInterval(() => setT(v => v + 1), ms);
return () => clearInterval(id); // 後片づけ
}, [ms]);
return t; // カスタム Hook は値を返す
}
-
ポイント:
useState
とuseEffect
を組み合わせて “タイマー機能” を独立パッケージ化。
2. 切り出した Hook をコンポーネントで使う
const seconds = useTimer(1000);
- ポイント: 普通の関数呼び出しと同じ書き心地で、タイマーの値をどこでも再利用できる。
Custom Hook の役割
自分だけの 再利用できる状態ロジック を作り、複数コンポーネントで共有する仕組み。
-
再利用性が高い
ひとつ書けば何度でも呼び出せる。 -
カプセル化できる
内部実装(state や effect)を隠し、外にシンプルな API だけを見せる。 -
コードが読みやすくなる
コンポーネントから “副作用のごちゃごちゃ” を追い出せる。
再利用性が高いとは?
同じ useState + useEffect
ロジックを毎回コピーするのは非効率。
Custom Hook にすれば 一か所に集約 でき、バグ修正・機能追加もその 1 ファイルだけ直せば済みます。
例:ウインドウ幅を追跡する Custom Hook
// useWindowWidth.js
import React from "react";
export function useWindowWidth() {
const [width, setWidth] = React.useState(window.innerWidth); // 現在幅
React.useEffect(() => {
const onResize = () => setWidth(window.innerWidth); // 幅を更新
window.addEventListener("resize", onResize); // リスナ登録
return () => window.removeEventListener("resize", onResize); // 後片づけ
}, []);
return width; // 今の幅を返す
}
// App.jsx
import React from "react";
import { useWindowWidth } from "./useWindowWidth";
export default function App() {
const w = useWindowWidth(); // Hook 呼び出し
return <p>ウインドウ幅: {w}px</p>; // 幅を表示
}
Custom Hook のベストプラクティス
-
関数名は必ず
use
で始める
React が “これは Hook だ” と認識してくれるお約束。 -
コンポーネントと同じルールを守る
フックを条件分岐の中で呼ばない、トップレベルで呼ぶなど基本ルールは同じ。