【React.js/Next.js】React API memo / React Hooks useMemo・useCallback 完全入門

React.js / Next.js

React API memoReact Hooks useMemo・useCallback は、どんな機能や違いがあるのかな?

今回は、React API である memoReact Hooks useMemouseCallback について、それぞれの違いや使い方、代表的なユースケースをわかりやすく解説します。

memo / useMemo / useCallback が生まれた背景

React.js は便利ですが、コンポーネントが更新されるたびにJSX やオブジェクト、配列、関数が毎回新しく生成 されます。

通常は問題になりませんが、次のような場合には 不要な処理が発生する 可能性があります。

  • 重い計算を毎回実行している
  • 子コンポーネントが大量にある
  • props が変わっていないのに再レンダリングされる

こうした問題を解決するために登場したのが、前回と同じなら再利用(メモ化)する という考え方で実現される memo / useMemo / useCallback です。

memo / useMemo / useCallback とは?

memo / useMemo / useCallback はすべて 再レンダリング最適化 を目的としていますが、何を再利用(メモ化)するか という点で役割が異なります。

useMemouseCallback 単体では、コンポーネントの再レンダリングは抑制されません。主に memo と組み合わせて使うことで、再レンダリング最適化 の効果を発揮します。

API・React Hookメモ化する対象処理効果
memoコンポーネントの描画結果props が前回と同じ場合に、コンポーネントの再レンダリングをスキップする子コンポーネントの再レンダリングを抑える
useMemo値(計算結果)依存配列が変わらない限り、値(計算結果)の再計算をスキップするprops に渡す値の参照を固定する
useCallback関数依存配列が変わらない限り、関数の再生成をスキップするprops に渡す関数の参照を固定する

使用する際の注意点

useCallback で 関数をメモ化(再利用)していても、それを受け取る子コンポーネントが memo でラップされていなければ、再レンダリングは発生 します。

逆に、memo を使っていても、props に毎回新しい関数やオブジェクトを渡している場合
props が変更されたと判定され、再レンダリングが発生 します。

コード例

memo

  • memo でコンポーネントの再描画を抑制しているため、MemoTitle のログが初回のみ表示
    Title のログは毎回表示される

🔹 useCallback

  • useCallback を設定していても、子コンポーネント側で memo していない場合、毎回レンダリングされてしまう
  • useCallback関数の再生成を抑制 しているため、 初回のみ MemoCountButton: CountDown のログが表示され、MemoCounter: Down は初回と更新時のみログが表示される
    CountButton: CountUp, Counter: Up のログは毎回表示される

🔹 useMemo

  • useMemo値の再計算を抑制 しているため、 UseMemoCounter: のログが初回と更新時のみ表示される
    NoUseMemoCounter: のログは毎回表示される

処理フロー

  1. 更新(リロード) ※全てログに表示され、レンダリングを確認
  2. カウントアップ ボタンを押す
    ログに「increment, NoUseMemoCounter, Title, Counter: Up, CountButton: CountUp」が表示され、レンダリングを確認
  3. 2回目の更新(リロード) ※全てログに表示され、レンダリングを確認
  4. カウントダウン ボタンを押す
    ログに「decrement, NoUseMemoCounter, Title, Counter: Up, CountButton: CountUp, MemoCounter: Down」が表示され、レンダリングを確認
  5. 3回目の更新(リロード) ※全てログに表示され、レンダリングを確認
  6. UseMemo カウントアップ ボタンを押す
    ログに「UseMemoCounter, NoUseMemoCounter, Title, Counter: Up, CountButton: CountUp」が表示され、レンダリングを確認

まとめ

React API である memoReact Hooks useMemouseCallback について、いかがでしたでしょうか?

memo / useMemo / useCallback はすべて 再レンダリング最適化 を目的としていますが、何を再利用するか(メモ化するか) という点で役割が異なります。
また useMemouseCallback は、 memo と組み合わせて使うことで 再レンダリング最適化 の効果を発揮します。

まずはそれぞれの使い方をしっかり押さえ、小さな コンポーネント から試しながら、少しずつ memo / useMemo / useCallback に慣れていきましょう。

公式サイト

tachu × tachu

Laravel / React フルスタックエンジニア

Webエンジニア歴15年、フリーランス歴8年で、PHP / Laravel を中心に、
React.js / Vue.js を用いたフルスタックでのWeb開発をしています。

技術記事は Laravel / React / Web開発 を中心に書いています。

Webサービスの開発、既存システム改善、機能追加、技術相談、小規模な開発など、お気軽にご相談ください。

React.js / Next.js
シェアする

コメント

タイトルとURLをコピーしました