【ITニュース解説】useMemo and useCallback Explained
2025年09月22日に「Dev.to」が公開したITニュース「useMemo and useCallback Explained」について初心者にもわかりやすく解説しています。
ITニュース概要
Reactの`useMemo`は、関数の計算結果を記憶し、依存値が変化しない限り再計算しない。`useCallback`は、関数そのものを記憶し、不要な再生成を防ぐ。これらを使うことで、コンポーネントのパフォーマンスを最適化できる。
ITニュース解説
ReactのようなモダンなJavaScriptフレームワークを使ってアプリケーションを開発していると、アプリケーションの動作が遅くなったり、不必要にリソースを消費したりすることがある。これを改善するための強力なツールがuseMemoとuseCallbackという二つの機能である。これらは「メモ化(Memoization)」というテクニックを使って、無駄な計算や処理を減らし、アプリケーションのパフォーマンスを最適化するために利用される。
まず「メモ化」とは、コンピュータプログラミングにおいて、関数の計算結果を記憶し、同じ入力が与えられた場合に、再度計算することなく記憶しておいた結果を返す最適化手法を指す。これは、計算コストが高い処理を何度も繰り返す必要がないようにするための仕組みである。
useMemoは「値をメモ化する」機能を提供する。これは、特定の計算の結果である「値」をキャッシュする。具体的には、ある関数が実行されて得られた結果を記憶しておき、その関数が次に呼ばれたときに、条件が満たされていれば記憶された値を再利用し、関数を再実行しないようにする。
useMemoを使う際、第一引数には計算を行って値を返す「ファクトリ関数」と呼ばれる関数を渡す。第二引数には「依存配列」と呼ばれる配列を渡す。この依存配列に含められた値のいずれかが前回のレンダリングから変更された場合にのみ、ファクトリ関数が再実行され、新しい値が計算される。もし依存配列内の値に変更がなければ、ファクトリ関数は実行されず、以前計算して記憶しておいた値がそのまま返される。
例えば、const sum = useMemo(() => a + b, [a, b]);という記述は、a + bという計算の結果をsumという変数に格納する。そして、この計算はaまたはbの値が変わったときのみ再実行される。もしコンポーネントが再レンダリングされてもaとbの値が変わっていなければ、a + bの計算はスキップされ、前回のsumの値が再利用される。これは、非常に複雑なデータ変換や重い処理の結果をキャッシュする際に特に有効で、不要な再計算を避けることでアプリケーションの応答性を高めることができる。
一方、useCallbackは「関数をメモ化する」機能を提供する。これは、特定の「関数そのもの」をキャッシュする。JavaScriptでは、コンポーネントが再レンダリングされるたびに、そのコンポーネント内で定義された関数は、たとえコードの内容が変わっていなくても、技術的には新しい関数として再作成されてしまうことがある。この「新しい関数」の生成が、場合によってはアプリケーションのパフォーマンスに悪影響を与える可能性がある。
useCallbackもuseMemoと同様に、第一引数にはメモ化したい関数、第二引数には依存配列を渡す。この依存配列に含まれる値が変化しない限り、useCallbackは前回のレンダリングで生成された「関数と同じ参照を持つ関数」を返す。つまり、コンポーネントが再レンダリングされても、その関数が新しいものとして再生成されるのを防ぎ、常に同じ関数インスタンスを参照するようにする。
例えば、const handleClick = useCallback(() => { console.log("Clicked!"); }, []);という記述では、クリックイベントを処理するhandleClick関数を定義している。依存配列が空の[]であるため、このhandleClick関数はコンポーネントが最初にマウントされたときに一度だけ作成され、その後コンポーネントが何度再レンダリングされても、その参照は変わらない。
この機能が特に役立つのは、親コンポーネントから子コンポーネントへ関数をプロップス(属性)として渡す場合である。もし親コンポーネントが再レンダリングされるたびに、渡す関数が新しいものとして再生成されると、子コンポーネントは「新しいプロップスを受け取った」と判断し、不必要に再レンダリングされてしまうことがある。しかし、useCallbackを使って関数をメモ化しておけば、子コンポーネントは同じ関数を受け取っていると判断できるため、不要な再レンダリングを防ぎ、パフォーマンスを向上させることが可能となる。
useMemoとuseCallbackの決定的な違いは、メモ化する対象である。
useMemoは、「この関数の実行結果(値)をキャッシュする」ものである。つまり、計算された結果であるa + bの「値」を記憶し、再利用する。
それに対してuseCallbackは、「この関数そのもの(関数の定義)をキャッシュする」ものである。つまり、handleClickという「関数」自体が毎回新しく作られるのを防ぎ、常に同じ関数を参照するようにする。
これらの機能を適切に利用することで、アプリケーションは不要な計算や再レンダリングを減らし、よりスムーズで高速な動作を実現できる。システムエンジニアを目指す上で、パフォーマンス最適化は重要なスキルの一つであり、これらのフックの概念と適切な利用シーンを理解することは、効率的で高品質なソフトウェア開発につながる。