VIDEO LESSON

Next.jsのuseState実践:カウンター・フォーム・状態更新の注意点の解説動画

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

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

  1. 0:00こんにちは。
  2. 0:00今回は、ネクストジェイエスのユーズステート実践です。
  3. 0:04カウンターと入力フォームを例に、状態の持ち方と更新の注意点を学びます。
  4. 0:09ユーズステートは、コンポーネントが画面の状態を記憶するためのリアクトのフックです。
  5. 0:16ボタンを押した回数やフォームの入力値など、操作に合わせて変わる値に使います。
  6. 0:21この動画では、タイプスクリプトとページズルーターを前提に、型推論、関数による更新、
  7. 0:27オブジェクトの更新を順に確認し、最後にアプリルーターでの境界まで説明します。
  8. 0:33記事はリアクト十八とネクストジェイエス十三のプロジェクトで使える例を前提にしていますが、
  9. 0:38考え方自体は現在のバージョンでも共通です。
  10. 0:43まず、なぜ普通の変数では足りないのかです。
  11. 0:46変数へ新しい値を代入しただけでは、リアクトは画面を描き直す必要があると分かりません。
  12. 0:53ユーズステートを使うと、現在の値と、更新するための関数がペアで返ります。
  13. 0:59更新関数を呼ぶことで、リアクトへ次の値と再描画を依頼できます。
  14. 1:04再描画のとき、コンポーネントは新しい状態を受け取って画面を作り直します。
  15. 1:10つまりユーズステートは、値を覚える場所と、画面更新の合図をまとめて提供する仕組みです。
  16. 1:17この関係を押さえると、以降の更新方法の違いが理解しやすくなります。
  17. 1:23ボタン操作や入力のように、利用者の行動で変わる値ほど、この仕組みの恩恵が分かりやすくなります。
  18. 1:31カウンターを作ります。
  19. 1:32ファイルは、エスアールシー配下のコンポーネンツフォルダーにある、カウンター・ティーエスエックスです。
  20. 1:40ユーズステートに初期値を渡すと、現在のカウントと、更新関数のセットカウントが返ります。
  21. 1:46この例では初期値が数値なので、状態の型はナンバーと推論され、毎回ユーズステートに型を明示する必要はありません。
  22. 1:55初期値はプロップスのイニシャルカウントで、省略時はゼロです。
  23. 1:59表示側はカウントをそのまま読みます。
  24. 2:02状態を作る行と、表示する行を分けて読むと、値の流れが追いやすくなります。
  25. 2:07前の値から次の値を計算するときは、更新関数を渡すのが安全です。
  26. 2:12画面のアドスリーは、現在の値を受け取って一を足す関数を三回渡します。
  27. 2:17リアクトは保留中の更新を順に適用するため、結果は三増えます。
  28. 2:22対して、セットカウントにカウント足す一を三回渡す書き方は、同じ描画時点のカウントから計算した同じ値を三回渡すことになり、
  29. 2:27一しか増えません。
  30. 2:33連続更新や、直前の値に依存する処理では、古い値を直接読まず、現在の値を受け取る関数形式を選んでください。
  31. 2:41これが状態更新で最もつまずきやすい点です。
  32. 2:44更新がキューに積まれて順に処理されるイメージを持つと、この差を間違えにくくなります。
  33. 2:50ページ側ではカウンターを読み込み、イニシャルカウントに十を渡して表示します。
  34. 2:56開発サーバーでスラッシュカウンターを開くと、最初に十が表示され、一増やすで十一、
  35. 3:01三増やすで十四、リセットで十へ戻る流れを確認できます。
  36. 3:07ここで大切なのは、イニシャルカウントは状態を作る最初の値だという点です。
  37. 3:12親からの値が後で変わっても、ユーズステートがそのたびに状態を作り直すわけではありません。
  38. 3:19親が値を管理すべき場合は、状態を親へ移し、値と更新用コールバックを渡す設計も検討します。
  39. 3:26リセットは、クリック時点の初期値へ明示的に戻す操作です。
  40. 3:30次にフォームです。
  41. 3:31プロフィールエディターでは、表示名と、お知らせ希望の真偽値を、一つのオブジェクト状態として持ちます。
  42. 3:39型はプロフィールで、ユーズステートに型引数で示し、初期値は空の名前とフォルスです。
  43. 3:45入力欄は、バリューにプロフィールの名前を渡し、変更イベントで入力値を受け取ります。
  44. 3:51更新では、現在のオブジェクトを展開してコピーし、名前だけを新しい値へ差し替えた、
  45. 3:55新しいオブジェクトを渡します。
  46. 3:59入力欄の値が状態と結び付くため、打つたびに下の表示名も連動します。
  47. 4:04制御された入力の基本形です。
  48. 4:06名前とお知らせ希望を別々の状態に分ける方法もありますが、まとめて扱うと提出時の処理が一か所に集まります。
  49. 4:13チェックボックス側も同じ考え方です。
  50. 4:16チェック状態をプロフィールのお知らせ希望と結び付け、変更時はチェックの真偽を受け取り、
  51. 4:21現在のオブジェクトをコピーしてその項目だけ差し替えます。
  52. 4:25注意点は、元のオブジェクトを直接書き換えないことです。
  53. 4:29ユーズステートの更新は、クラス部品のようにオブジェクトの一部を自動で結合しません。
  54. 4:34残したい項目はスプレッドでコピーし、新しいオブジェクトとして渡してください。
  55. 4:39入れ子になったオブジェクトでは、変更する階層まで新しい値を作る必要があります。
  56. 4:45表示名が空なら未入力と出す分岐も、状態を読むだけの処理です。
  57. 4:49実行タイミングと型の注意点です。
  58. 4:51更新関数を呼んでも、実行中のイベント処理の中では、状態変数はすぐには変わりません。
  59. 4:58新しい値を受け取るのは次の描画です。
  60. 5:01途中で古い値を読んで処理を続けると、想定とずれることがあります。
  61. 5:06また、フックはコンポーネントやカスタムフックのトップレベルで呼び、条件分岐やループの中へ置きません。
  62. 5:14呼び出し順序が毎回同じであることが前提だからです。
  63. 5:18型については、初期値だけでは意図が伝わらない場合に型引数を使います。
  64. 5:23たとえば文字列またはヌルを許す状態は、ユーズステートにその型を示してヌルで始めます。
  65. 5:30開発時のストリクトモードにも注意します。
  66. 5:33ストリクトモードでは、初期化関数や更新関数が追加で実行されることがあります。
  67. 5:40そのため、これらの関数の中では、値を計算する処理だけを行ってください。
  68. 5:46通信、ログ送信、外部の配列やオブジェクトの変更といった副作用を入れると、
  69. 5:52追加実行によって二重に起きたり、結果がぶれたりします。
  70. 5:57前の値を受け取って次の値を返す、純粋な計算として書くのが原則です。
  71. 6:03問題が起きたときに、入力が同じなら出力も同じになる形だと、原因を切り分けやすくなります。
  72. 6:10本番だけの問題と決めつけず、開発時の挙動も前提に設計しましょう。
  73. 6:16アプリルーターで使う場合です。
  74. 6:18状態やイベントを扱うコンポーネントは、クライアントコンポーネントの境界内へ置きます。
  75. 6:24たとえばカウンターの先頭で、インポートより前にユーズクライアントを指定します。
  76. 6:30すべての親ページをクライアント化する必要はなく、状態を持つ部品だけを境界内に寄せるのが基本です。
  77. 6:37もう一つ、クライアントコンポーネントも初回表示用にサーバーで描画されることがあります。
  78. 6:43描画時にブラウザーの情報へ無条件に触れる実装は避け、必要な同期はユーズエフェクトへ分けてください。
  79. 6:50サーバーで値が存在しない前提を忘れないことが大切です。
  80. 6:54最後に確認のしかたです。
  81. 6:56一回のクリックだけでなく、連続更新や、リセットした後の再操作まで試してください。
  82. 7:03前の状態から次を計算する場合は、関数型の更新で同じ描画内の更新を正しく扱えるかを見ます。
  83. 7:11また、プロップスを初期値に使っても、その後のプロップス変更が自動で状態へ反映されるわけではありません。
  84. 7:20親で値を管理するのか、入力途中の値を子に保持するのかを先に決めることが、
  85. 7:25設計の分かれ目です。
  86. 7:29まとめです。
  87. 7:30値を覚えるのはユーズステート、前の値からの計算は関数形式、オブジェクトは新しい値を作って更新。
  88. 7:38この三点を押さえれば、カウンターもフォームも安全に実装できます。
  89. 7:44迷ったら、値がどこで生まれ、誰が更新し、誰が読むのかを書き出してから実装すると整理できます。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Next.jsでuseStateを使う実践入門。カウンターと入力フォームから、型推論、関数による更新、オブジェクトの更新、Pages RouterとApp Routerの違いを解説します。

解説記事・サンプルコードを読む:Next.jsのuseState実践:カウンター・フォーム・状態更新の注意点 →