コース一覧
React状態管理:カスタムフック・Context・Reducer
つくる - フック化完了

React状態管理:カスタムフック・Context・Reducer

カスタムフック、フックのルール、Context、useContext、useReducer、Actionのunion型を扱う全21レッスンの状態管理コースです。fleamaの商品・フォーム・テーマ・ユーザー・カート状態を、再利用可能なロジックと予測可能な状態遷移へ整理します。

1
カスタムフック
01. なぜカスタムフックか10分
02. useItemsを作る15分
03. useFormを作る15分
04. フックのルール15分
05. フックに型を付ける15分
06. つくる - フック化完了20分
07. 第4章クイズ15分
2
useContext
01. バケツリレーの限界15分
02. Contextを作る15分
03. useContextで使う15分
04. テーマの全体共有15分
05. ユーザー情報の共有15分
06. つくる - Context整備20分
07. 第5章クイズ15分
3
useReducer
01. setStateの散らかり15分
02. useReducer15分
03. Actionのunion型15分
04. カートreducer15分
05. 使い分け10分
06. つくる - カート完成20分
07. 第6章クイズ15分

つくる - フック化完了

画面のファイルから、通信と入力を追い出す

第4章の締めくくりです。新しいことは出てきません。ここまでの4つを使って、App.tsx を「見た目を組み立てるだけのファイル」にします。

  • useItems に取得をまとめる
  • useForm に入力をまとめる
  • フックのルールを守る
  • 戻り値に型を付ける

送信もフックの仕事にする

いまの App.tsx は、一覧の取得は useItems に任せているのに、出品の POST だけ自分で fetch を呼んでいます。これでは商品データを触る場所が2つに分かれたままです。同じデータを扱う処理は、同じフックに集めます。

TypeScript (JSX)

export type UseItemsResult = { items: Item[]; loading: boolean; error: string | null; addItem: (input: NewItem) => Promise<void>; };

addItem の型は「NewItem を受け取って、終わったことだけを知らせる関数」という意味です。返す約束をしていないので、使う側は結果ではなく完了だけを待ちます。

送ったあとに、なぜ画面が変わるのか

addItem の中では、POST の返事を items の末尾に足します。

TypeScript (JSX)

const made: Item = await res.json(); setItems((prev) => [...prev, made]);

サーバーが決めた id 付きの1件が返ってくるので、それをそのまま state に足します。state を書き換えるのはフックの中だけになり、App.tsx には setItems が1つも出てきません。

App.tsx に残るもの

残るのは、フックを呼ぶ2行と JSX だけです。

TypeScript (JSX)

const { items, loading, error, addItem } = useItems(""); const { values, handleChange, reset } = useForm({ title: "", price: "" });

ここまで来ると、ロジックの層と見た目の層が分かれます。第5章から先で状態の共有や画面の分割をしても、この2つのフックはほとんど書き換えずに済みます。

演習

addItem と useForm を仕上げ、App.tsx から fetch と入力欄の state を無くします。

ヒント

POST は fetch の第2引数に method と headers と body を渡します。body は JSON.stringify で文字にします

返ってきた1件は await res.json() で受け取り、setItems((prev) => [...prev, made]) で足します

App.tsx の handleSubmit は await addItem(...) のあとに reset() を呼ぶだけになります

App.tsx
mock-api.json
useForm.ts
useItems.ts
プレビュー

できているか

  • 一覧が API から5件出ている
  • 出品するとリストに1件増える
  • POST が useItems.ts にある
  • useForm が values を書き換えている
  • App.tsx が useForm を呼んでいる
  • App.tsx に fetch が残っていない
  • 入力欄の state が App.tsx から消えている
エディタを読み込んでいます