VIDEO LESSON

Next.jsのuseContext入門:Providerでテーマと状態を共有するの解説動画

再生時間 7:39動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

  1. 0:00こんにちは。
  2. 0:00今回は、ネクストジェイエスのユーズコンテキスト入門です。
  3. 0:05テーマ切り替えを例に、プロバイダーでテーマと状態を共有する方法を学びます。
  4. 0:10ユーズコンテキストは、祖先にあるプロバイダーから値を受け取るリアクトのフックです。
  5. 0:17テーマや表示設定のように、複数の部品が必要とする値を、中間の部品へ何段もプロップスで渡さずに共有できます。
  6. 0:25この動画では、ページズルーターとタイプスクリプトを使い、型付きプロバイダーと専用フックを作り、
  7. 0:30最後にアプリルーターでの配置の違いまで確認します。
  8. 0:36まず、なぜコンテキストが必要なのかです。
  9. 0:39親から孫、さらにその先へ同じ値を渡し続けると、中間の部品が自分では使わない値まで受け取って渡す、
  10. 0:44いわゆるバケツリレーが起きます。
  11. 0:50部品が増えるほど、受け渡しの経路が読みにくくなります。
  12. 0:54コンテキストを使うと、祖先のプロバイダーが用意した値を、必要な子孫が直接読み取れます。
  13. 1:01ただし大切な区別があります。
  14. 1:03ユーズコンテキストは値を届ける仕組みであり、状態そのものを自動で作る機能ではありません。
  15. 1:10状態の保持と更新には、ユーズステートなどを組み合わせます。
  16. 1:15近くの親子で完結する受け渡しなら、プロップスのほうが流れを追いやすい場合もあります。
  17. 1:22テーマを共有するコンテキストを実装します。
  18. 1:25ファイルは、エスアールシー配下のコンテキストフォルダーにある、テーマコンテキスト・ティーエスエックスです。
  19. 1:32画面に示した前半では、まずテーマの型をライトとダークの二択に限定し、共有する値の型として、
  20. 1:37現在のテーマと切り替え関数をまとめたテーマバリューを定義します。
  21. 1:43次にクリエイトコンテキストでコンテキストを作ります。
  22. 1:46ここへ渡す初期値は、対応するプロバイダーが祖先にない場合のフォールバックです。
  23. 1:52この例ではアンディファインドを使い、配置忘れを後で専用フックで検出できるようにします。
  24. 1:58コンテキストはモジュールのトップレベルで一度だけ定義し、描画のたびに作り直しません。
  25. 2:03続いてプロバイダー本体です。
  26. 2:05テーマプロバイダーは、ユーズステートでテーマを保持し、初期値はライトです。
  27. 2:10切り替え関数のトグルテーマは、現在の値を受け取り、ライトならダークへ、ダークならライトへ反転させます。
  28. 2:17関数形式で更新するため、古い値に依存しない安全な書き方になっています。
  29. 2:22用意したテーマと切り替え関数を、バリューとしてコンテキストプロバイダーへ渡し、
  30. 2:25子要素をその内側に置きます。
  31. 2:29トグルテーマが値を更新すると、そのコンテキストを読む子孫へ新しい値が伝わります。
  32. 2:34なおこの例ではブラウザーの保存領域を使わないため、ページを完全に再読み込みすると、
  33. 2:38初期値のライトへ戻ります。
  34. 2:42次に、ページズルーターの共通部分へプロバイダーを配置します。
  35. 2:46ファイルはアンダースコアエーピーピー・ティーエスエックスです。
  36. 2:50全ページを表すコンポーネントをテーマプロバイダーで囲むことで、どのページからでも同じテーマを読めるようになります。
  37. 2:58既存のアンダースコアエーピーピーがある場合は、グローバルシーエスエスやレイアウトなどの処理を残し、
  38. 3:03プロバイダーで必要な範囲だけを囲んでください。
  39. 3:08サンプルでファイル全体を上書きして、既存の設定を失わないようにすることが大切です。
  40. 3:13同じプロバイダーがマウントされたままのクライアント側のページ移動では状態を共有できますが、
  41. 3:17プロバイダーをページごとに作り直す場合や、ブラウザーを再読み込みする場合は、
  42. 3:22状態の寿命が変わります。
  43. 3:26読み取り側は、専用フックのユーズテーマを用意します。
  44. 3:30このフックは内部でユーズコンテキストを呼び、取得した値をチェックします。
  45. 3:34もし値がアンディファインドなら、プロバイダーの内側で使われていないということなので、
  46. 3:39エラーを投げて配置忘れをすぐ気付けるようにします。
  47. 3:43チェックを通過すれば、型がテーマバリューに確定した値を返します。
  48. 3:47利用側は、ユーズテーマを呼ぶだけで、テーマと切り替え関数を取り出せます。
  49. 3:52毎回コンテキストを直接読み、未定義かどうかを各部品で繰り返し判定する必要がなくなり、
  50. 3:56使い方も統一できます。
  51. 3:59この一手間が、大きなアプリでの事故防止につながります。
  52. 4:03子コンポーネントから読み取りと更新を行う例です。
  53. 4:06テーマボタンは、ユーズテーマから現在のテーマと切り替え関数を受け取ります。
  54. 4:12ボタンをクリックするとトグルテーマが呼ばれ、押下状態を示すエーリアプレストには、
  55. 4:15ダークかどうかを渡します。
  56. 4:19表示文字も、ダークなら有効、そうでなければ無効と切り替わります。
  57. 4:24ポイントは、このボタンへテーマをプロップスで渡す必要がないことです。
  58. 4:29親がテーマを知らなくても、ボタン自身がコンテキストから直接読むため、間に部品が増えても受け渡しを書き足す必要がありません。
  59. 4:38ページ側の例です。
  60. 4:39テーマページもユーズテーマでテーマを読み、背景色と文字色を、ダークかどうかで切り替えます。
  61. 4:45ページの中には先ほどのテーマボタンが置かれています。
  62. 4:49開発サーバーでスラッシュテーマへアクセスすると、ボタンとページが同じテーマを参照し、
  63. 4:54クリックで表示がまとめて切り替わることが確認できます。
  64. 4:59ボタンが状態を更新し、ページがその結果を描くという役割分担です。
  65. 5:04どちらもプロバイダーが持つ一つの状態を見ているため、値が食い違うことがありません。
  66. 5:10共有したい値と、それを使う場所が離れているほど、この仕組みの効果が分かりやすくなります。
  67. 5:16再描画と値の管理に注意します。
  68. 5:19プロバイダーの値が変わると、コンテキストを読むコンポーネントは更新を受け取ります。
  69. 5:26値の比較にはオブジェクトイズが使われます。
  70. 5:30この例のバリューは新しいオブジェクトとして渡されるため、プロバイダーが別の理由で再描画された場合にも参照が変わり、
  71. 5:36読む側が更新されることがあります。
  72. 5:42実際に不要な再描画が問題になったら、コンテキストの責務を分ける、プロバイダーの配置を狭める、
  73. 5:50必要に応じてユーズメモやユーズコールバックで値を安定させる、といった方法を検討します。
  74. 5:57ただしメモ化しても、テーマ自体が変わった際の利用側の更新は必要です。
  75. 6:03対策は、実測してから入れてください。
  76. 6:06アプリルーターでの利用です。
  77. 6:08プロバイダーのファイルはユーズクライアントで始め、クライアントコンポーネントとして用意し、
  78. 6:12必要な部分を囲みます。
  79. 6:16サーバーコンポーネントのレイアウトから、そのプロバイダーを読み込んで子要素を渡すことはできます。
  80. 6:23ただし、サーバーコンポーネント自身がユーズコンテキストでクライアントの状態を読む構成にはできません。
  81. 6:30境界を意識して、状態を持つ部分だけをクライアント側へ寄せるのが基本です。
  82. 6:35あわせてセキュリティの注意です。
  83. 6:38コンテキストはアクセス権限を保証する仕組みではありません。
  84. 6:42表示名などを共有する用途には使えますが、認証と認可はサーバー側でも確認し、
  85. 6:47秘密のエーピーアイキーをコンテキストへ入れてブラウザーへ渡すことは避けてください。
  86. 6:53最後に、コンテキストを広げすぎない設計です。
  87. 6:56まず、テーマや設定を必要とする部品を確認し、必要な範囲にプロバイダーを置きます。
  88. 7:03アプリ全体で本当に必要なのか、画面の一部で足りるのかを考えてください。
  89. 7:08次に、更新頻度の違う値を整理します。
  90. 7:11頻繁に変わる入力値と、ほとんど変わらない設定を同じコンテキストへまとめると、
  91. 7:16利用側の更新範囲が広がる場合があります。
  92. 7:20実際の描画を確認し、役割に応じて分割するか判断します。
  93. 7:25まとめです。
  94. 7:25クリエイトコンテキストで入れ物を作り、プロバイダーがユーズステートで状態を持ち、
  95. 7:30専用フックで安全に読む。
  96. 7:34この三点セットを押さえれば、テーマ共有を自分で実装できます。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Next.jsでuseContextを使い、テーマを共有する実践例を紹介。型付きProvider、専用Hook、更新と再描画、Pages RouterとApp Routerの配置の違いを解説します。

解説記事・サンプルコードを読む:Next.jsのuseContext入門:Providerでテーマと状態を共有する →