VIDEO LESSON

Next.jsのuseEffect実践:依存配列・後始末・SSRでの注意点の解説動画

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

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

  1. 0:00こんにちは。
  2. 0:00今回は、ネクストジェイエスのユーズエフェクト実践です。
  3. 0:04タイマーとブラウザーイベントを例に、依存配列、後始末、エスエスアールでの注意点を学びます。
  4. 0:11ユーズエフェクトは、リアクトの画面と、ブラウザーの機能やタイマー、外部サービスなどを同期するためのフックです。
  5. 0:19描画が確定した後に処理を始め、値の変更や画面の破棄に合わせて後片付けをします。
  6. 0:25この動画では、タイプスクリプトとページズルーターを前提に、開始と停止が対になる設計を中心に説明します。
  7. 0:32前提のバージョンは記事と同じ、リアクト十八とネクストジェイエス十三の例ですが、
  8. 0:37考え方は現在のバージョンでも共通です。
  9. 0:41まず、ユーズエフェクトの役割です。
  10. 0:44これは、描画後に何でも実行する場所ではありません。
  11. 0:48画面と外部の仕組みを同期させるための場所です。
  12. 0:51たとえば、タイマーを動かす、画面サイズの変化を購読する、外部サービスとつなぐ、
  13. 0:55といった処理が対象です。
  14. 0:59反対に、表示用の値を計算するだけなら、描画中に計算できます。
  15. 1:04また、エフェクトはサーバーでのエイチティーエムエル生成時には実行されません。
  16. 1:10ブラウザーで画面が確定してから初めて動く、という前提が、後のエスエスアールの注意につながります。
  17. 1:18同期が必要かどうかが、エフェクトを使うかどうかの判断基準になります。
  18. 1:23まず目的を言葉にしてから書き始めることが大切です。
  19. 1:27タイマーの例です。
  20. 1:29ファイルは、エスアールシー配下のコンポーネンツフォルダーにある、イラプストセカンズ・ティーエスエックスです。
  21. 1:37ランニングが真なら、一秒ごとに秒数を増やすタイマーを開始します。
  22. 1:42エフェクトが関数を返している点に注目してください。
  23. 1:45この返した関数が後始末で、タイマーを止める役割を持ちます。
  24. 1:50ランニングが偽へ変わるときや、部品が破棄されるときに、前のエフェクトの後始末が先に呼ばれます。
  25. 1:57なおこの例はタイマーの呼び出し回数を数えるため、裏側のタブでは遅れることがあります。
  26. 2:03開始した処理には必ず対応する後始末を用意する、という対の考え方が、この後のすべての例に共通する原則になります。
  27. 2:12ページ側では、ランニングという真偽値の状態を持ち、ボタンで切り替えます。
  28. 2:17開発サーバーでスラッシュタイマーを開くと、最初はタイマーが進み、停止を押すと数値が増えなくなり、
  29. 2:22再開すると続きから増えます。
  30. 2:26別ページへ移動して戻ったときも、以前のタイマーが残って二重に進まないことが大切です。
  31. 2:32これが確認できれば、開始と後始末が正しく対になっている証拠です。
  32. 2:37逆に、停止しても増え続ける場合は、後始末が呼ばれていないか、タイマーが複数残っている可能性を疑います。
  33. 2:44確認は一度だけでなく、停止と再開を何度か繰り返し、移動と復帰も含めて行うと、
  34. 2:49後始末の漏れに気付きやすくなります。
  35. 2:53依存配列の読み方です。
  36. 2:55角括弧のランニングは、再実行してよい回数を示すものではありません。
  37. 3:01エフェクトが参照する、変化に反応する値を示す宣言です。
  38. 3:05依存配列を省略すると、描画が確定するたびに実行されます。
  39. 3:11空の配列は、そのエフェクトが反応する値に依存していないことを示します。
  40. 3:17タイマーの例では、現在の値を受け取る関数形式で秒数を更新するため、セカンズ自体を依存配列へ追加せずに済みます。
  41. 3:27警告を消すためだけに必要な値を外すと、古い値を参照する原因になるので注意してください。
  42. 3:35依存配列は、エフェクトが外のどの変化に反応すべきかを、コード上で明示する場所だと理解すると、
  43. 3:40書き方で迷いにくくなります。
  44. 3:45開発時のストリクトモードにも注意します。
  45. 3:48ストリクトモードでは、問題を見つけるために、開始、後始末、再開始が追加で行われることがあります。
  46. 3:56そのため、空の依存配列を、必ず一度しか実行しない保証と考えるのは正確ではありません。
  47. 4:02大切なのは、タイマーやイベント購読が、何度開始と停止を繰り返しても整合するように設計することです。
  48. 4:10後始末を正しく書いておけば、追加実行でもタイマーは一つだけ残り、二重に進むことはありません。
  49. 4:17開発時だけの不具合に見えても、後始末の不足を示すサインとして受け止めましょう。
  50. 4:23後始末が正しければ、追加実行は不具合ではなく、設計の弱点を見つけるための検査として働いてくれることになります。
  51. 4:31次にブラウザーイベントの例です。
  52. 4:34ファイルはウィンドウウィドゥス・ティーエスエックスです。
  53. 4:38幅の状態は、数値またはヌルで、初期値はヌルです。
  54. 4:42エフェクトでは、まず現在の幅を測って状態へ入れ、リサイズイベントへ同じ関数を登録します。
  55. 4:49後始末では、登録したのと同じ関数を渡して購読を解除します。
  56. 4:54登録と解除で別の関数を渡すと解除できないため、関数を変数に入れて共有する書き方が重要です。
  57. 5:01スライドでは表示崩れを避けるため、元のテンプレート文字列を文字列の連結で表示していますが、
  58. 5:06意味は同じです。
  59. 5:10購読の解除を忘れると、画面を離れても処理が残り続け、戻るたびに登録が増えていくため、
  60. 5:15動作が次第に重くなる原因になります。
  61. 5:20エスエスアールでの注意点です。
  62. 5:22サーバーにはウィンドウが存在しないため、描画中に画面幅を読むことはできません。
  63. 5:27そこで幅の初期値をヌルにし、サーバーとブラウザーの最初の描画を、どちらも確認中という同じ表示にそろえます。
  64. 5:34その後、エフェクトでブラウザーの幅を読み取って表示を切り替えます。
  65. 5:39最初の表示がサーバーとブラウザーで食い違うと、表示のずれや警告の原因になります。
  66. 5:44また、単なる見た目の切り替えなら、ジャバスクリプトで幅を測る前に、シーエスエスのメディアクエリで実現できるかも確認しましょう。
  67. 5:52ブラウザーでしか得られない値は、描画中ではなくエフェクトで読み取る、という役割分担がエスエスアール対応の基本になります。
  68. 6:00通信の注意点です。
  69. 6:02エフェクト自体を非同期関数にすると、後始末の代わりにプロミスを返してしまいます。
  70. 6:08通信が必要なら、エフェクトの中で非同期関数を定義して呼び出し、後始末ではフラグを倒すなどして、
  71. 6:14終わった画面へ古い結果を反映しないようにします。
  72. 6:19中断にはアボートコントローラーを使う方法もあります。
  73. 6:23一方、購入や投稿など、利用者の操作に対応する処理は、通常はクリックや送信のイベントハンドラーに置きます。
  74. 6:31エフェクトを使う前に、何と同期する必要があるのかを必ず確認してください。
  75. 6:37通信結果が届く順序は保証されないため、古い結果で新しい表示を上書きしない工夫も、
  76. 6:41実務ではあわせて必要になります。
  77. 6:46アプリルーターで使う場合です。
  78. 6:48エフェクトを使う部品は、クライアントコンポーネントの境界内へ置き、境界ファイルの先頭でユーズクライアントを指定します。
  79. 6:55ただし、クライアントコンポーネントだからといって、エフェクトがサーバー上で動くわけではありません。
  80. 7:00エフェクトはあくまでブラウザーで描画が確定した後に実行されます。
  81. 7:04ページ全体を境界に入れる必要はなく、タイマーやイベントなど、ブラウザーと同期が必要な部品だけを境界内に寄せるのが基本です。
  82. 7:11サーバーで完結する表示は、サーバー側に残しておきましょう。
  83. 7:15境界を小さく保つほど、サーバー側で描画できる範囲が広がり、表示の速さや検索への対応でも有利になることがあります。
  84. 7:21最後に、エフェクトが必要かを見直します。
  85. 7:24プロップスや状態から計算できる表示値を、エフェクトで別の状態へコピーする必要がないか検討してください。
  86. 7:32外部との同期と、描画中にできる計算を分けるだけで、余分な更新を減らせます。
  87. 7:37確認では、タイマーやイベントについて、部品の取り外しと再表示でも重複しないことを試します。
  88. 7:44まとめです。
  89. 7:45開始と後始末を対にする、依存配列は参照する値の宣言として書く、最初の描画はサーバーとそろえる。
  90. 7:51この三点を押さえれば、ユーズエフェクトを安全に使えます。
  91. 7:56迷ったときは、何と同期するのか、後始末は何か、依存する値はどれか、の三つを書き出してから実装すると整理できます。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Next.jsのuseEffectをタイマーとブラウザイベントの例で解説。依存配列、クリーンアップ、Strict Mode、サーバー描画、非同期処理の注意点を学べます。

解説記事・サンプルコードを読む:Next.jsのuseEffect実践:依存配列・後始末・SSRでの注意点 →