Hooksの使い分け — 判断フローと横断比較
ここまで5つのフックを個別に学んできました。 この章では全体を俯瞰して、「この場面ではどのフックを使うべきか」を迷わず判断できるようにします。
学習者フックが5つも出てきて頭がごちゃごちゃ…。結局どの場面でどれを使えばいいの?
5つのフックの横断比較
各フックの性質を整理します。
useState — UIに影響する値を管理する。値を変更すると再レンダーが走り、画面が更新される。
useRef — UIに影響しない値を保持する。DOM参照、タイマーID、前回の値など。変更しても再レンダーは起きない。
useEffect — レンダー後に外部と同期する。API呼び出し、購読、タイマーなど。クリーンアップ関数で後始末ができる。
useMemo — 重い計算結果をキャッシュする。依存が変わらない限り前回の結果を返す。レンダー中に同期実行。
useCallback — 関数オブジェクトをキャッシュする。useMemoの関数特化版。React.memoされた子コンポーネントへのpropsや、useEffectの依存配列で参照を安定させたいときに使う。
判断フローチャート
「値を持ちたい」「処理を実行したい」「パフォーマンスを改善したい」という3つの出発点から、どのフックに辿り着くかを示します。
値を持ちたい場合
処理を実行したい場合
子コンポーネントへの受け渡しを最適化したい場合
よくある疑問
useMemoとuseCallbackはどう使い分ける?
メモ化したい対象が「値」なら useMemo、「関数」なら useCallback です。useCallback は useMemo の関数特化版なので、useMemo(() => () => { ... }, [deps]) と書けば useCallback と同じことができますが、意図の明確さから関数には useCallback を使います。
useRefとuseMemoの違いがわからない
useRef は自分で .current を書き換えるまでずっと同じ値を持ち続けます。useMemo は依存配列が変わったら自動で再計算します。
「タイマーIDを保持する」→ 自動再計算は不要 → useRef。
「ユーザーリストをソートした結果を保持する」→ 元データが変わったら再計算 → useMemo。
useEffectとuseMemoは両方とも依存配列があるけど何が違う?
実行タイミングが異なります。useMemo はレンダー中に同期的に実行され、すぐに値を返します。useEffect はレンダーが完了してDOMに反映された後に実行されます。
「ソートした結果を今すぐJSXで使いたい」→ useMemo。
「APIからデータを取得したい」→ useEffect。
useCallbackを使っているのにパフォーマンスが改善しない
受け取る側の子コンポーネントが React.memo でラップされていない可能性が高いです。useCallback 単体では効果がなく、参照の安定性を活用する側(React.memo、useEffect の依存配列)があって初めて意味を持ちます。
カスタムフックへの導線
5つのフックを組み合わせた処理が複数のコンポーネントで重複するようになったら、カスタムフックとして切り出せます。
// useWindowSize — ウィンドウサイズを監視するカスタムフック
function useWindowSize() {
const [size, setSize] = useState({ width: 0, height: 0 });
useEffect(() => {
const handleResize = () => {
setSize({ width: window.innerWidth, height: window.innerHeight });
};
handleResize(); // 初期値を設定
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
// 使う側
function Header() {
const { width } = useWindowSize();
return <header>{width < 768 ? 'モバイル' : 'デスクトップ'}</header>;
}カスタムフックは use で始まる関数で、中で他のフックを自由に使えます。「イベントリスナーの登録(useEffect)+ 値の管理(useState)」のような定型パターンを1つの関数にまとめられます。
カスタムフック自体は本書のスコープ外ですが、5つのフックを理解していれば、既存のカスタムフックのコードを読んだときに「ああ、useEffectで購読してuseStateで値を管理しているのか」と構造がわかるようになります。
まとめ
5つのフックはそれぞれ異なる役割を持っています。
useState はUIに影響する状態を管理し、変更時に再レンダーを引き起こします。useRef はUIに影響しない値を再レンダーなしに保持します。useEffect はレンダー後に外部との同期処理を実行します。useMemo は重い計算結果をキャッシュし、useCallback は関数オブジェクトをキャッシュします。
判断の起点は「その値は画面に映るか」「その処理はレンダーの結果として必要か」「参照の安定性を受け取る側が活用するか」の3つです。
これでReactのHooksの土台は固まりました。この先Next.jsなどのフレームワークに進むと、Server ComponentやApp Routerなど新しい概念が出てきますが、それらの理解もここで学んだHooksの知識が基盤になります。