コース一覧
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分

フックに型を付ける

フックに渡す型

戻り値の型は、フックの取扱説明書

useItems は items と loading と error を返します。型を書かないままだと、使う側にはこう見えます。

TypeScript (JSX)

const result = useItems("shoes"); result.itmes.map(...) // 打ち間違いに誰も気付かない

戻り値に any を付けているのも同じです。any は「何でもある」ではなく「検査をやめる」という意味なので、存在しない項目を書いても通ってしまいます。フックの戻り値の型は、使う人が読む唯一の説明書です。

型に名前を付けて返す

型を独立させ、関数の戻り値として書きます。

TypeScript (JSX)

export type UseItemsResult = { items: Item[]; loading: boolean; error: string | null; }; export function useItems(category: string): UseItemsResult { ... return { items, loading, error }; }

こう書くと3つの得があります。

  • 使う側で items と打った時点で候補が出る。綴りを間違えたらその場で赤くなる
  • 返し忘れると useItems 側が怒られる。使う側で気付くより早い
  • 型に名前が付くので、他のファイルからも UseItemsResult として読める

error の型は string ではなく string | null

エラーが無いときは何も無い、という状態を型に書きます。string | null にしておくと、使う側は if (error) で分けるまで中身を文字として扱えません。「まだ無い」を型で表しておくと、無いときの分岐を書き忘れられなくなります。

配列で返すか、オブジェクトで返すか

useState は [value, setValue] という配列を返します。2つで、順番が決まっていて、名前を呼ぶ側が自由に決めたいからです。一方カスタムフックは3つ以上を返すことが多く、順番で覚えるのは無理があります。3つ以上を返すならオブジェクトにすると考えて構いません。

演習

useItems の戻り値に型を付け、使う側で loading と error を出し分けます。

ヒント

export type UseItemsResult = { items: Item[]; loading: boolean; error: string | null }; の形です

戻り値の型は function useItems(category: string): UseItemsResult { と書きます

件数は items.length で取れます

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

できているか

  • 取得のあいだ読み込み中が出ている
  • くつが2件並んでいる
  • 件数が出ている
  • 戻り値の型に名前を付けている
  • error を string | null で表している
  • any で逃げていない
  • 使う側が loading を見ている
エディタを読み込んでいます