VIDEO LESSON

ReactのuseApiData:API通信のloading・error・再取得を管理するの解説動画

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

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

  1. 0:00こんにちは。
  2. 0:00リアクト入門の第十一回です。
  3. 0:03今回は、エーピーアイ通信の状態を管理するカスタムフック、ユースエーピーアイデータを学びます。
  4. 0:10前回は、ジェイソン取得の手順をフェッチジェイソンという関数にまとめました。
  5. 0:16ただ、画面側にはまだ、読み込み中かどうか、失敗したかどうか、取得したデータ、
  6. 0:21といった状態の管理が残っています。
  7. 0:25今回は、その状態管理ごとフックに切り出して、画面のコードをすっきりさせる方法です。
  8. 0:32通信の中止や、古い結果で表示を上書きしない仕組み、再取得まで含めて進めましょう。
  9. 0:38まず、前回とのつながりです。
  10. 0:40フェッチジェイソンは、ユーアールエルからジェイソンを取得し、失敗したらエラーを投げる、
  11. 0:45という通信の手順だけを担当する関数でした。
  12. 0:49フックは使っていないので、状態は持っていません。
  13. 0:52そのため、使う画面ごとに、ローディング、エラー、データの三つのステートと、
  14. 0:57取得開始から終了までの更新手順を書く必要がありました。
  15. 1:01画面が増えるほど、同じ管理コードが重複します。
  16. 1:04ユースエーピーアイデータは、この重複する状態管理をまとめるためのカスタムフックです。
  17. 1:10画面側は、フックが返す状態を見て表示を切り替えるだけに近づきます。
  18. 1:15ユースエーピーアイデータの契約を見ます。
  19. 1:18引数は取得先のユーアールエルです。
  20. 1:21戻り値は四つで、取得したデータ、エラーメッセージ、ローディングかどうか、
  21. 1:25そして再取得を実行するリロード関数です。
  22. 1:30内部では、結果を一つのオブジェクトにまとめて保持します。
  23. 1:35その形が、スライドのリーズルト型です。
  24. 1:38ユーアールエル、データ、エラー、ローディングの四項目です。
  25. 1:42結果にユーアールエルも一緒に保存する点が、後で出てくる、古い結果を表示しない工夫につながります。
  26. 1:50データの型は、前回と同じくアンノウン、つまり未検証のままです。
  27. 1:55フックは取得までを担当し、中身の検証は画面側の仕事として残します。
  28. 2:01実装に入ります。
  29. 2:02ファイルは、エスアールシー配下のフックスフォルダーに、ユースエーピーアイデータ・ティーエスとして置きます。
  30. 2:10フックの中では、二つのステートを使います。
  31. 2:13一つ目はリーズルトで、現在の通信結果そのものです。
  32. 2:17初期値は、データなし、エラーなし、ローディングは真、つまり最初から読み込み中として始まります。
  33. 2:24最初に画面が表示されたらすぐに取得が始まる前提だからです。
  34. 2:29二つ目はバージョンで、再取得の回数を数えるだけの数です。
  35. 2:33役割の違う二つの値を分けることで、データの状態と、もう一度取得したいという合図を、
  36. 2:37混ぜずに扱えます。
  37. 2:41中心はユースエフェクトです。
  38. 2:43依存値はユーアールエルとバージョンの二つで、どちらかが変わると取得がやり直されます。
  39. 2:49処理の流れは四段階です。
  40. 2:51まず、アボートコントローラーを作り、このエフェクトが有効だというアクティブの印を立てます。
  41. 2:58次に、リーズルトを読み込み中に戻します。
  42. 3:01そしてフェッチジェイソンにユーアールエルと中止用のシグナルを渡して取得し、
  43. 3:07成功したらデータを、失敗したらエラーメッセージを、それぞれローディングを偽にして保存します。
  44. 3:14最後に後始末です。
  45. 3:15そのエフェクトが終わるときは、アクティブを偽にして結果を無効化し、コントローラーのアボートで通信の中止も要求します。
  46. 3:24開始と後始末を常に対にすることが、このフックの土台です。
  47. 3:28通信で怖いのは、古い結果が新しい表示を上書きしてしまう競合です。
  48. 3:33このフックは二重に防ぎます。
  49. 3:36一つ目はアクティブの印です。
  50. 3:38後始末が終わったエフェクトの結果は、成功でも失敗でも、ステートに入れずに捨てます。
  51. 3:45中止の要求だけに頼らず、更新の直前でも確認するのがポイントです。
  52. 3:50二つ目はユーアールエルの照合です。
  53. 3:53返却前に、保存された結果のユーアールエルが今のユーアールエルと一致するかを見ます。
  54. 3:59違えば、前のデータは見せず、読み込み中として扱います。
  55. 4:04ユーアールエルを変えた直後の画面に、前のページの内容が一瞬でも残らないための配慮です。
  56. 4:11再取得のリロードは、バージョンを一つ増やすだけの小さな関数です。
  57. 4:16再取得の仕組みを、もう少し詳しく見ます。
  58. 4:19リロード関数は、バージョンのステートに一つを足すだけです。
  59. 4:24すると、エフェクトの依存値であるバージョンが変わるため、エフェクトがもう一度実行され、
  60. 4:29前の通信の後始末を挟んで、新しい取得が始まります。
  61. 4:34ボタン側はリロードを呼ぶだけでよく、通信をどうやり直すかを知る必要がありません。
  62. 4:41逆にフック側も、ボタンが何回押されたかではなく、バージョンという数だけを見ています。
  63. 4:47この分離のおかげで、自動更新のように別のきっかけで再取得したくなったときも、
  64. 4:51同じ仕組みをそのまま使えます。
  65. 4:56画面側のアプリ・ティーエスエックスです。
  66. 4:59使い方はシンプルで、ユースエーピーアイデータにユーアールエルを渡し、データ、
  67. 5:04エラー、ローディング、リロードを受け取るだけです。
  68. 5:08使うファイルは前回と同じ、メッセージ・ジェイソンです。
  69. 5:13フックから届くデータは未検証なので、画面側でメッセージが文字列かどうかを確かめ、
  70. 5:16取り出します。
  71. 5:20再取得ボタンは、クリックでリロードを呼び、ローディング中は無効化されます。
  72. 5:26前回は画面側に並んでいた取得処理と状態更新が消え、表示の分岐だけが残りました。
  73. 5:32前回と見比べると、共通化の効果がよく分かります。
  74. 5:35表示の切り替えには、決まった順番があります。
  75. 5:39最初にローディングを見て、真なら読み込み中と表示します。
  76. 5:43次にエラーを見て、あればアラートとして表示します。
  77. 5:48そのどちらでもないときに初めて、データの中身を確認します。
  78. 5:52検証に失敗していれば、データ形式が不正ですと伝え、問題なければメッセージを表示します。
  79. 5:59順番が大切なのは、ヌルという値が、未取得でも失敗でも使われるからです。
  80. 6:05値だけでは成功かどうかを判定できません。
  81. 6:08状態を表すローディングとエラーを先に見ることで、判定がぶれません。
  82. 6:14なお、空の文字列のメッセージは、正常なデータとしてそのまま表示します。
  83. 6:20空かどうかと、形式が正しいかどうかは、別の話として扱います。
  84. 6:24動作確認では、遅い通信をわざと作って試します。
  85. 6:28ブラウザーの開発者ツールで通信速度を遅くし、取得の途中で対象のコンポーネントを非表示にしてください。
  86. 6:37後始末によって、中止が要求されるはずです。
  87. 6:40次に、ユーアールエルをエーからビーへ変えた場合です。
  88. 6:44エーの通信が遅れて完了しても、ビーの結果を上書きしないことを確認します。
  89. 6:50開発時のストリクトモードでは、エフェクトが追加で実行されることがありますが、
  90. 6:56開始と後始末が対になっていれば、結果は正しく保たれます。
  91. 7:01今回、こうした成功、失敗、再取得、中止の状態遷移をモックで実行し、記事の期待と一致することを確認しました。
  92. 7:10最後に、このフックの限界も正直に押さえます。
  93. 7:13キャッシュ、重複したリクエストの集約、自動のリトライ、タイムアウト、サーバー側での事前取得は、
  94. 7:17どれも含まれていません。
  95. 7:22同じユーアールエルを複数か所で使えば、通信もステートも場所ごとに別になります。
  96. 7:27要件が増えたら、フレームワークの取得機能や、データ取得ライブラリとの比較が次の選択肢です。
  97. 7:34また、購入や登録のような送信処理をエフェクトの中で行わないことも大切で、
  98. 7:37それは次回のポストの話題です。
  99. 7:41まとめると、ユースエーピーアイデータは、ローディング、エラー、データ、再取得と、
  100. 7:45中止と競合の抑止をまとめた小さなフックです。
  101. 7:50なお、ブラウザー上で実際にボタンを押す確認は、実行環境の制約で未実施です。
  102. 7:55次回はポストジェイソンでフォーム送信を学びます。
  103. 7:58お疲れさまでした。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

API取得を独自Hookへ切り出し、読み込み・失敗・成功、中止、古い通信結果の抑止、再取得を実装します。

解説記事・サンプルコードを読む:ReactのuseApiData:API通信のloading・error・再取得を管理する →