VIDEO LESSON
ReactのuseReducer入門:TypeScriptで買い物リストの状態更新を整理するの解説動画
再生時間 7:55動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00リアクト入門の第三回です。
- 0:02今回は、ユースリデューサーを使って、状態の更新ルールを一か所へ整理する方法を学びます。
- 0:09入力値やチェック状態だけなら、ユースステートが便利です。
- 0:13でも、追加、購入済みの切り替え、削除のように、更新の種類が増えてくると、
- 0:17更新のたびに処理があちこちへ散らばりやすくなります。
- 0:22そこで、買い物リストを題材に、ステート、アクション、リデューサーの役割を、
- 0:26タイプスクリプトのコードで一つずつ確認していきましょう。
- 0:31まず、三つの言葉の関係を整理します。
- 0:34ステートは現在のデータです。
- 0:36この例では、商品の配列がステートになります。
- 0:39アクションは、何をしたいかを表す値です。
- 0:42追加したい、切り替えたい、削除したい、といった操作の種類を表します。
- 0:47リデューサーは、現在のステートとアクションを受け取り、次のステートを計算する関数です。
- 0:53コンポーネントは、ディスパッチという関数でアクションを渡します。
- 0:58すると、リデューサーが次のステートを返し、画面は新しいステートから組み立て直されます。
- 1:04大切なのは、すべての値を一つのリデューサーへまとめなくてよいことです。
- 1:09入力中の商品名は、別のユースステートで管理します。
- 1:13更新ルールは、ショッピングリデューサー・ティーエスというファイルにまとめます。
- 1:20まず、商品の型であるアイテムを定義します。
- 1:23アイディー、名前、そして購入済みかどうかを示すダンを持ちます。
- 1:28次に、アクションの型です。
- 1:30追加のときは商品そのものが必要で、切り替えと削除のときはアイディーが必要だと、
- 1:34型で表せます。
- 1:38このように、操作の種類ごとに必要な情報が違う形を、判別可能なユニオン型と呼びます。
- 1:45初期データは、未購入の牛乳と、購入済みのパンの二件です。
- 1:49種類を取り違えたアクションを書くと、タイプスクリプトがエラーで教えてくれます。
- 1:56リデューサー本体は、アクションのタイプで分岐します。
- 2:00追加では、元の配列を広げて、新しい商品を加えた配列を返します。
- 2:06切り替えでは、マップで配列をたどり、アイディーが一致した商品だけ、ダンを反転させた新しいオブジェクトを作ります。
- 2:16一致しない商品は、そのまま使います。
- 2:19削除では、フィルターで対象以外を残した配列を返します。
- 2:24実機でも確認しました。
- 2:26初期は二件で未購入は一件、りんごを追加すると三件になり、牛乳を切り替えると未購入は一件減ります。
- 2:34削除では、指定した商品だけが消えました。
- 2:38どの分岐も、元の配列は書き換えていません。
- 2:41リデューサーを書くときの約束が二つあります。
- 2:45一つ目は、元のステートを変更しないことです。
- 2:48プッシュで配列へ追加したり、商品のダンを直接書き換えたりせず、新しい配列やオブジェクトを返します。
- 2:56変更しない要素は、同じオブジェクトを再利用できます。
- 3:00二つ目は、同じステートとアクションからは、必ず同じ結果を返す純粋な関数にすることです。
- 3:06そのため、通信やストレージへの保存、乱数によるアイディー生成は、リデューサーの中に入れません。
- 3:14アイディーは、後で見るイベント処理で作って、アクションへ含めます。
- 3:19さらにこの例では、アサートネバーという仕組みで、将来アクションの種類を増やしたのに分岐を書き忘れた場合、
- 3:24型エラーで気づけるようにしています。
- 3:30次に、画面側のショッピングリスト・ティーエスエックスを作ります。
- 3:34ユースリデューサーに、リデューサーと初期データを渡すと、現在のアイテムズと、
- 3:39アクションを送るディスパッチが返ってきます。
- 3:43一方、入力中の商品名は、ユースステートで別に保持します。
- 3:48リストの更新ルールには関係しない、一時的な入力値だからです。
- 3:52未購入の件数は、専用のステートを作らず、アイテムズをフィルターして数えます。
- 3:58すでに持っているデータから計算できる値は、描画の中で求めるのが基本です。
- 4:03保存する値を増やすほど、更新の漏れが起きやすくなります。
- 4:08操作は、ディスパッチで伝えます。
- 4:10フォームを送信したら、まず商品名の前後の空白を取り除き、空なら何もしません。
- 4:16空でなければ、クリプト・ランダムユーユーアイディーで一時的なアイディーを作り、
- 4:21追加のアクションを送って、入力欄を空に戻します。
- 4:26この仕組みは、安全な接続の環境で使う点も押さえてください。
- 4:30チェックボックスが変わったら、切り替えのアクションと商品のアイディーを送ります。
- 4:36削除ボタンでは、削除のアクションを送ります。
- 4:40ボタンの読み上げ用の名前には商品名を含めるので、どの商品を消すのかが伝わります。
- 4:46画面側は、何をしたいかだけを伝え、更新の計算はリデューサーへ任せる形です。
- 4:52入口のアプリ・ティーエスエックスは、シンプルです。
- 4:55見出しとショッピングリストを並べるだけで、状態の管理はショッピングリスト側に任せます。
- 5:01メイン・ティーエスエックスは、バイトのテンプレートのまま使えます。
- 5:06一覧の行には、配列の位置ではなく、商品のアイディーをキーに指定します。
- 5:11追加と削除を繰り返しても、購入済みの状態が別の商品へ移らないようにするためです。
- 5:16今回、記事のコードそのままを、タイプスクリプトの厳密な型チェックにかけ、
- 5:20エラーがないことを確認しました。
- 5:23ブラウザー上での実際の描画と操作の確認は、実行環境の制約で未実施です。
- 5:28その代わり、リデューサーの計算はノード・ジェーエスで実行して確かめています。
- 5:34動作確認は、記事の手順どおりに進めます。
- 5:37初期状態は、全二件、未購入一件です。
- 5:40空欄や、空白だけの商品名は追加できません。
- 5:44りんごを追加すると全三件になり、入力欄は空になります。
- 5:49未購入の商品をチェックすると、未購入の数が一つ減ります。
- 5:53削除ボタンでは、対象の商品だけが消えます。
- 5:57すべて削除すると、買うものを追加してください、という案内が表示されます。
- 6:03あわせて、ビルドを実行して、型エラーや読み込みの漏れがないことも確かめましょう。
- 6:10リデューサーをテストするときは、追加後の件数だけでなく、元の配列が変わっていないことや、
- 6:18指定したアイディーだけが切り替わることも確認すると、ルールの誤りに気づきやすくなります。
- 6:26よくある疑問を二つ取り上げます。
- 6:28一つ目は、ディスパッチを呼んだ直後にステートが変わらないのはなぜか、です。
- 6:34ディスパッチは、次の描画に向けた更新の依頼です。
- 6:38呼び出したイベント処理の途中で、今見えているアイテムズという変数が、その場で書き換わるわけではありません。
- 6:46更新後の表示は、次の描画で確認してください。
- 6:50二つ目は、ストリクトモードでリデューサーが追加で呼ばれても大丈夫か、です。
- 6:56開発中は、追加の呼び出しが起きることがあります。
- 6:59でも、元のステートを変更せず、乱数や通信を含まない純粋な処理なら、商品が二重に追加されることはありません。
- 7:08純粋さを保つ約束が、ここで効いてきます。
- 7:11まとめです。
- 7:12ユースリデューサーは、更新の種類が増えたときに、ステート、アクション、リデューサーで更新ルールを一か所へ集める方法です。
- 7:20ただし、ユースステートから必ず移行しなければならないわけではありません。
- 7:25単純な入力値や開閉の状態には、ユースステートのほうが読みやすい場合があります。
- 7:30更新の種類が増えた、同じルールが複数のイベントに散らばった、更新処理だけを検証したい。
- 7:36そんな理由が出てきたときに、ユースリデューサーを検討してください。
- 7:41練習として、購入済みをまとめて削除するアクションを追加し、型と分岐をそろえて書いてみましょう。
- 7:47次回は、ユースアイディーで、ラベルと説明を入力フォームに関連付ける方法を学びます。
- 7:53お疲れさまでした。
この動画で学べること
React公式リファレンスを参考に、useReducerで買い物リストを実装。TypeScriptのaction型、dispatch、純粋な更新関数、追加・購入済み切り替え・削除を学びます。
解説記事・サンプルコードを読む:ReactのuseReducer入門:TypeScriptで買い物リストの状態更新を整理する →