WEBVTT

1
00:00:00.000 --> 00:00:00.976
こんにちは。

2
00:00:00.976 --> 00:00:03.252
リアクト入門の第十一回です。

3
00:00:03.252 --> 00:00:10.731
今回は、エーピーアイ通信の状態を管理するカスタムフック、ユースエーピーアイデータを学びます。

4
00:00:10.731 --> 00:00:16.747
前回は、ジェイソン取得の手順をフェッチジェイソンという関数にまとめました。

5
00:00:16.747 --> 00:00:21.219
ただ、画面側にはまだ、読み込み中かどうか、失敗したかどうか、取得したデータ、

6
00:00:21.219 --> 00:00:25.690
といった状態の管理が残っています。

7
00:00:25.690 --> 00:00:32.356
今回は、その状態管理ごとフックに切り出して、画面のコードをすっきりさせる方法です。

8
00:00:32.356 --> 00:00:38.860
通信の中止や、古い結果で表示を上書きしない仕組み、再取得まで含めて進めましょう。

9
00:00:38.860 --> 00:00:40.793
まず、前回とのつながりです。

10
00:00:40.793 --> 00:00:45.213
フェッチジェイソンは、ユーアールエルからジェイソンを取得し、失敗したらエラーを投げる、

11
00:00:45.213 --> 00:00:49.632
という通信の手順だけを担当する関数でした。

12
00:00:49.632 --> 00:00:52.947
フックは使っていないので、状態は持っていません。

13
00:00:52.947 --> 00:00:57.366
そのため、使う画面ごとに、ローディング、エラー、データの三つのステートと、

14
00:00:57.366 --> 00:01:01.786
取得開始から終了までの更新手順を書く必要がありました。

15
00:01:01.786 --> 00:01:04.962
画面が増えるほど、同じ管理コードが重複します。

16
00:01:04.962 --> 00:01:10.763
ユースエーピーアイデータは、この重複する状態管理をまとめるためのカスタムフックです。

17
00:01:10.763 --> 00:01:15.320
画面側は、フックが返す状態を見て表示を切り替えるだけに近づきます。

18
00:01:15.320 --> 00:01:18.578
ユースエーピーアイデータの契約を見ます。

19
00:01:18.578 --> 00:01:21.347
引数は取得先のユーアールエルです。

20
00:01:21.347 --> 00:01:25.908
戻り値は四つで、取得したデータ、エラーメッセージ、ローディングかどうか、

21
00:01:25.908 --> 00:01:30.469
そして再取得を実行するリロード関数です。

22
00:01:30.469 --> 00:01:35.030
内部では、結果を一つのオブジェクトにまとめて保持します。

23
00:01:35.030 --> 00:01:38.125
その形が、スライドのリーズルト型です。

24
00:01:38.125 --> 00:01:42.848
ユーアールエル、データ、エラー、ローディングの四項目です。

25
00:01:42.848 --> 00:01:50.667
結果にユーアールエルも一緒に保存する点が、後で出てくる、古い結果を表示しない工夫につながります。

26
00:01:50.667 --> 00:01:55.717
データの型は、前回と同じくアンノウン、つまり未検証のままです。

27
00:01:55.717 --> 00:02:01.092
フックは取得までを担当し、中身の検証は画面側の仕事として残します。

28
00:02:01.092 --> 00:02:02.318
実装に入ります。

29
00:02:02.318 --> 00:02:10.438
ファイルは、エスアールシー配下のフックスフォルダーに、ユースエーピーアイデータ・ティーエスとして置きます。

30
00:02:10.438 --> 00:02:13.655
フックの中では、二つのステートを使います。

31
00:02:13.655 --> 00:02:17.486
一つ目はリーズルトで、現在の通信結果そのものです。

32
00:02:17.486 --> 00:02:24.686
初期値は、データなし、エラーなし、ローディングは真、つまり最初から読み込み中として始まります。

33
00:02:24.686 --> 00:02:29.130
最初に画面が表示されたらすぐに取得が始まる前提だからです。

34
00:02:29.130 --> 00:02:33.419
二つ目はバージョンで、再取得の回数を数えるだけの数です。

35
00:02:33.419 --> 00:02:37.250
役割の違う二つの値を分けることで、データの状態と、もう一度取得したいという合図を、

36
00:02:37.250 --> 00:02:41.080
混ぜずに扱えます。

37
00:02:41.080 --> 00:02:43.222
中心はユースエフェクトです。

38
00:02:43.222 --> 00:02:49.646
依存値はユーアールエルとバージョンの二つで、どちらかが変わると取得がやり直されます。

39
00:02:49.646 --> 00:02:51.482
処理の流れは四段階です。

40
00:02:51.482 --> 00:02:58.365
まず、アボートコントローラーを作り、このエフェクトが有効だというアクティブの印を立てます。

41
00:02:58.365 --> 00:03:01.424
次に、リーズルトを読み込み中に戻します。

42
00:03:01.424 --> 00:03:07.772
そしてフェッチジェイソンにユーアールエルと中止用のシグナルを渡して取得し、

43
00:03:07.772 --> 00:03:14.120
成功したらデータを、失敗したらエラーメッセージを、それぞれローディングを偽にして保存します。

44
00:03:14.120 --> 00:03:15.497
最後に後始末です。

45
00:03:15.497 --> 00:03:24.369
そのエフェクトが終わるときは、アクティブを偽にして結果を無効化し、コントローラーのアボートで通信の中止も要求します。

46
00:03:24.369 --> 00:03:28.652
開始と後始末を常に対にすることが、このフックの土台です。

47
00:03:28.652 --> 00:03:33.879
通信で怖いのは、古い結果が新しい表示を上書きしてしまう競合です。

48
00:03:33.879 --> 00:03:36.166
このフックは二重に防ぎます。

49
00:03:36.166 --> 00:03:38.453
一つ目はアクティブの印です。

50
00:03:38.453 --> 00:03:45.150
後始末が終わったエフェクトの結果は、成功でも失敗でも、ステートに入れずに捨てます。

51
00:03:45.150 --> 00:03:50.377
中止の要求だけに頼らず、更新の直前でも確認するのがポイントです。

52
00:03:50.377 --> 00:03:53.154
二つ目はユーアールエルの照合です。

53
00:03:53.154 --> 00:03:59.851
返却前に、保存された結果のユーアールエルが今のユーアールエルと一致するかを見ます。

54
00:03:59.851 --> 00:04:04.261
違えば、前のデータは見せず、読み込み中として扱います。

55
00:04:04.261 --> 00:04:11.285
ユーアールエルを変えた直後の画面に、前のページの内容が一瞬でも残らないための配慮です。

56
00:04:11.285 --> 00:04:16.512
再取得のリロードは、バージョンを一つ増やすだけの小さな関数です。

57
00:04:16.512 --> 00:04:19.659
再取得の仕組みを、もう少し詳しく見ます。

58
00:04:19.659 --> 00:04:24.222
リロード関数は、バージョンのステートに一つを足すだけです。

59
00:04:24.222 --> 00:04:29.572
すると、エフェクトの依存値であるバージョンが変わるため、エフェクトがもう一度実行され、

60
00:04:29.572 --> 00:04:34.922
前の通信の後始末を挟んで、新しい取得が始まります。

61
00:04:34.922 --> 00:04:41.216
ボタン側はリロードを呼ぶだけでよく、通信をどうやり直すかを知る必要がありません。

62
00:04:41.216 --> 00:04:47.824
逆にフック側も、ボタンが何回押されたかではなく、バージョンという数だけを見ています。

63
00:04:47.824 --> 00:04:51.994
この分離のおかげで、自動更新のように別のきっかけで再取得したくなったときも、

64
00:04:51.994 --> 00:04:56.164
同じ仕組みをそのまま使えます。

65
00:04:56.164 --> 00:04:59.240
画面側のアプリ・ティーエスエックスです。

66
00:04:59.240 --> 00:05:04.086
使い方はシンプルで、ユースエーピーアイデータにユーアールエルを渡し、データ、

67
00:05:04.086 --> 00:05:08.931
エラー、ローディング、リロードを受け取るだけです。

68
00:05:08.931 --> 00:05:13.084
使うファイルは前回と同じ、メッセージ・ジェイソンです。

69
00:05:13.084 --> 00:05:16.699
フックから届くデータは未検証なので、画面側でメッセージが文字列かどうかを確かめ、

70
00:05:16.699 --> 00:05:20.314
取り出します。

71
00:05:20.314 --> 00:05:26.005
再取得ボタンは、クリックでリロードを呼び、ローディング中は無効化されます。

72
00:05:26.005 --> 00:05:32.004
前回は画面側に並んでいた取得処理と状態更新が消え、表示の分岐だけが残りました。

73
00:05:32.004 --> 00:05:35.696
前回と見比べると、共通化の効果がよく分かります。

74
00:05:35.696 --> 00:05:39.306
表示の切り替えには、決まった順番があります。

75
00:05:39.306 --> 00:05:43.901
最初にローディングを見て、真なら読み込み中と表示します。

76
00:05:43.901 --> 00:05:48.003
次にエラーを見て、あればアラートとして表示します。

77
00:05:48.003 --> 00:05:52.762
そのどちらでもないときに初めて、データの中身を確認します。

78
00:05:52.762 --> 00:05:59.818
検証に失敗していれば、データ形式が不正ですと伝え、問題なければメッセージを表示します。

79
00:05:59.818 --> 00:06:05.561
順番が大切なのは、ヌルという値が、未取得でも失敗でも使われるからです。

80
00:06:05.561 --> 00:06:08.843
値だけでは成功かどうかを判定できません。

81
00:06:08.843 --> 00:06:14.258
状態を表すローディングとエラーを先に見ることで、判定がぶれません。

82
00:06:14.258 --> 00:06:20.001
なお、空の文字列のメッセージは、正常なデータとしてそのまま表示します。

83
00:06:20.001 --> 00:06:24.924
空かどうかと、形式が正しいかどうかは、別の話として扱います。

84
00:06:24.924 --> 00:06:28.746
動作確認では、遅い通信をわざと作って試します。

85
00:06:28.746 --> 00:06:37.055
ブラウザーの開発者ツールで通信速度を遅くし、取得の途中で対象のコンポーネントを非表示にしてください。

86
00:06:37.055 --> 00:06:40.545
後始末によって、中止が要求されるはずです。

87
00:06:40.545 --> 00:06:44.866
次に、ユーアールエルをエーからビーへ変えた場合です。

88
00:06:44.866 --> 00:06:50.848
エーの通信が遅れて完了しても、ビーの結果を上書きしないことを確認します。

89
00:06:50.848 --> 00:06:56.332
開発時のストリクトモードでは、エフェクトが追加で実行されることがありますが、

90
00:06:56.332 --> 00:07:01.816
開始と後始末が対になっていれば、結果は正しく保たれます。

91
00:07:01.816 --> 00:07:10.624
今回、こうした成功、失敗、再取得、中止の状態遷移をモックで実行し、記事の期待と一致することを確認しました。

92
00:07:10.624 --> 00:07:13.760
最後に、このフックの限界も正直に押さえます。

93
00:07:13.760 --> 00:07:17.966
キャッシュ、重複したリクエストの集約、自動のリトライ、タイムアウト、サーバー側での事前取得は、

94
00:07:17.966 --> 00:07:22.172
どれも含まれていません。

95
00:07:22.172 --> 00:07:27.732
同じユーアールエルを複数か所で使えば、通信もステートも場所ごとに別になります。

96
00:07:27.732 --> 00:07:34.147
要件が増えたら、フレームワークの取得機能や、データ取得ライブラリとの比較が次の選択肢です。

97
00:07:34.147 --> 00:07:37.782
また、購入や登録のような送信処理をエフェクトの中で行わないことも大切で、

98
00:07:37.782 --> 00:07:41.418
それは次回のポストの話題です。

99
00:07:41.418 --> 00:07:45.837
まとめると、ユースエーピーアイデータは、ローディング、エラー、データ、再取得と、

100
00:07:45.837 --> 00:07:50.257
中止と競合の抑止をまとめた小さなフックです。

101
00:07:50.257 --> 00:07:55.531
なお、ブラウザー上で実際にボタンを押す確認は、実行環境の制約で未実施です。

102
00:07:55.531 --> 00:07:58.953
次回はポストジェイソンでフォーム送信を学びます。

103
00:07:58.953 --> 00:08:00.236
お疲れさまでした。
