VIDEO LESSON
ReactのuseMemoとuseCallback:商品検索で学ぶメモ化の使い分けの解説動画
再生時間 7:34動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00リアクト入門の第五回です。
- 0:02今回は、ユースメモとユースコールバックで、メモ化の使い分けを学びます。
- 0:08メモ化とは、一度作った結果を覚えておき、条件が変わらなければ再利用する考え方です。
- 0:14題材は、キーボードやマウスなどの商品を名前で絞り込む、商品検索です。
- 0:19計算結果を覚える場合と、関数の参照を覚える場合では、使うフックが変わります。
- 0:25どちらも最初からすべての部品へ付けるものではありません。
- 0:29タイプスクリプトの小さなコードで、違いを一つずつ確認していきましょう。
- 0:34まず、三つの機能を区別します。
- 0:36ユースメモは、依存する値が変わらない間、計算した値を再利用するためのフックです。
- 0:43ユースコールバックは、依存する値が変わらない間、関数の参照、つまり関数そのものの同一性を再利用するためのフックです。
- 0:51メモは、プロップスが変わらないときに、親の更新に伴う部品の再レンダーを省略できるようにする仕組みです。
- 0:59いずれも最適化のための機能です。
- 1:02もしメモ化を外したら動作が壊れるなら、それは最適化とは別の設計の問題かもしれません。
- 1:08画面の正しさを、キャッシュが残ることに頼らないようにしましょう。
- 1:13商品一覧の部品、プロダクトリスト・ティーエスエックスを作ります。
- 1:19親から受け取るプロップスは、商品の配列プロダクツと、選択を伝えるオンセレクトの二つです。
- 1:26部品全体をメモで包むことで、プロップスが変わらないときは再レンダーを省略できる形にします。
- 1:34商品がゼロ件なら、該当する商品がありません、という案内を表示します。
- 1:40一件以上あれば、商品名と価格と、選ぶためのボタンを並べます。
- 1:45なお、一覧のキーは商品のアイディーです。
- 1:48ここで大切なのは、一覧自身の作りではなく、親から渡される二つのプロップスが安定するかどうかです。
- 1:57メモの標準の比較では、各プロップスをオブジェクトイズで比べます。
- 2:02親がレンダーのたびに新しい配列や関数を作って渡すと、中身が同じように見えても、
- 2:07参照は別のものになります。
- 2:11その場合は、メモで包んでいても再レンダーは省略されません。
- 2:16逆に言えば、親の側で配列と関数の参照を安定させれば、メモが効く土台ができます。
- 2:23子の中のボタンで作る小さな関数は、親子の比較対象ではありません。
- 2:28この例で比べられるのは、プロダクツとオンセレクトの二つだけです。
- 2:34どこが比較対象なのかを絞ることが、メモ化の出発点です。
- 2:39親の部品、プロダクトサーチでは、検索語から表示する商品を計算します。
- 2:45入力されたクエリをトリムで前後の空白を取り除き、小文字にそろえたものをキーワードとします。
- 2:54ビジブルプロダクツはユースメモで作ります。
- 2:58中では、商品名を小文字にそろえ、キーワードを含むものだけをフィルターで残します。
- 3:06依存配列はキーワードだけです。
- 3:09キーワードが変われば計算し直し、同じなら前に作った配列をそのまま再利用できます。
- 3:16商品データは部品の外にある固定データなので、依存配列には入りません。
- 3:23もしエーピーアイから受け取る配列なら、その配列も依存値になります。
- 3:29次に、選択用の関数ハンドルセレクトを、ユースコールバックで作ります。
- 3:35商品が選ばれたら、そのアイディーをセレクトアイディーというステートへ入れます。
- 3:41この関数が使うのは、安定したステート更新関数だけなので、依存配列は空です。
- 3:47ユースコールバックに渡した関数は、フックを呼んだ時点では実行されません。
- 3:53あくまで、ボタンが押されたときに実行される関数を、参照を変えずに保持するだけです。
- 3:59もし変わるステートやプロップスの関数を読む処理を加えたら、その値を依存配列へ含めてください。
- 4:06古い値を読み続ける不具合を、最適化と引き換えに持ち込まないことが大切です。
- 4:12アプリ・ティーエスエックスでは、見出しとプロダクトサーチを配置するだけです。
- 4:19動作を確認します。
- 4:20初期状態は検索結果が三件で、選択中はなし、です。
- 4:24マウスと検索すると一件になります。
- 4:27マウスを選ぶボタンを押すと、選択中の表示がマウスに変わります。
- 4:32検索条件を変えても、選択中の商品は維持されます。
- 4:37存在しない商品名ではゼロ件の案内が出ます。
- 4:40そして、検索のヒントを開閉しても、検索結果や選択状態は変わりません。
- 4:46ヒントの開閉はキーワードを変えないため、ユースメモの配列の参照も維持され、
- 4:52メモ化した一覧の再レンダーを省略できる構造になっています。
- 4:57依存配列は、回数を抑えるための都合で決めるものではありません。
- 5:02計算や関数の中で読む値のうち、変わる可能性があるものが依存値です。
- 5:06ユースメモではキーワード、ユースコールバックでは今回は何もありません。
- 5:12ここで、なぜ商品配列が入らないのかをもう一度確認します。
- 5:16プロダクツは部品の外に置かれた固定データで、レンダーのたびに作り直されることがないからです。
- 5:22もし商品をステートやプロップスで管理するなら話は変わり、依存配列に含める必要があります。
- 5:29依存値を正しく書くことが、メモ化を安全に使う前提です。
- 5:33最適化を入れるかどうかは、先に計測して判断します。
- 5:36今回のように商品が数件なら、単純にフィルターするだけでも通常は十分です。
- 5:41この小さな例は、高速化が必要だと主張するものではなく、仕組みを学ぶためのものです。
- 5:47実際に遅さを感じたら、リアクト開発者ツールのプロファイラーなどで、対象のレンダーを調べましょう。
- 5:54比べるときは、同じデータ量と操作を使います。
- 5:57開発時のストリクトモードによる追加実行と、本番環境の動作は区別してください。
- 6:02ヒント開閉時に一覧のプロップスが維持されることだけでは、アプリ全体が速くなったとは結論づけられません。
- 6:09落とし穴を三つ挙げます。
- 6:11一つ目、レンダーのたびに新しい設定オブジェクトを作って依存配列に入れると、
- 6:15参照が毎回変わるため、毎回計算し直してしまいます。
- 6:20必要な文字列を直接依存値にするか、設定は計算の中で作る方法を検討します。
- 6:25二つ目、メモで包んでも、その部品自身のステートや、読み取っているコンテキストが変われば更新されます。
- 6:32手動の比較関数を書く場合は、関数のプロップスも含めて比べる必要があります。
- 6:37三つ目、リアクトコンパイラーが有効な環境では、自動的なメモ化で手動の指定が必要な場面が減ります。
- 6:44バージョンだけで判断せず、プロジェクトのビルド設定を確認してください。
- 6:49まとめです。
- 6:50計算した値を再利用したいときはユースメモ、関数の参照を再利用したいときはユースコールバック、
- 6:56そして子の再レンダーを省略したいときはメモ、と役割で使い分けます。
- 7:02三つは単独ではなく、親で参照を安定させ、子をメモで包むことで、初めて効果がつながります。
- 7:08今回、記事のコードそのままをタイプスクリプトの厳密な型チェックにかけて、
- 7:12エラーがないことを確認しました。
- 7:16絞り込みの計算もノード・ジェーエスで実行して確かめています。
- 7:21ブラウザー上での実際の描画や、再レンダーの回数の目視確認は、実行環境の制約で未実施です。
- 7:27次回は、ユーストランジションとユースディファードバリューを学びます。
- 7:32お疲れさまでした。
この動画で学べること
ReactのuseMemo・useCallback・memoの違いを商品検索のコードで解説。依存配列、propsの参照、React Compilerとの関係、計測して最適化する判断を学びます。
解説記事・サンプルコードを読む:ReactのuseMemoとuseCallback:商品検索で学ぶメモ化の使い分け →