コース一覧
React状態管理:カスタムフック・Context・Reducer
useContextで使う

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分

useContextで使う

useContext が探しに行く

箱から取り出す

前の回で作った ThemeContext は、まだ誰も覗いていません。覗くのが useContext です。

TypeScript (JSX)

import { useContext } from "react"; import { ThemeContext } from "./ThemeContext"; function PriceTag({ price }: PriceTagProps) { const theme = useContext(ThemeContext); return <p className={"price " + theme}>{price} 円</p>; }

useContext(ThemeContext) は、自分より上にあるいちばん近い Provider の value を返します。PriceTag が何段深くても、間に何があっても関係ありません。props を1つも受け取らずに theme が手に入ります。

戻り値の型は、箱を作るときに書いた <Theme> から決まります。ここで theme.toUpperCase() のような打ち間違いをすれば、その場で止まります。

バケツリレーを消す

取り出せるようになったので、途中の受け渡しは要らなくなります。

  • ItemListProps から theme を消す
  • ItemCardProps から theme を消す
  • 呼び出しの theme={theme} を消す

ItemList と ItemCard が、商品を並べるという本来の仕事だけを持つ形に戻ります。使う人が直接取りに行くので、通り道になる部品がいなくなるわけです。

Provider が無いとどうなるか

useContext は、上に Provider が見つからないと既定値を返します。作るときに書いた "light" です。

エラーにならないので気付きにくいのが厄介なところです。「切り替えても何も変わらない」という不具合の多くは、Provider の外側で useContext を呼んでいるのが原因です。既定値は、そういうときの目印になる値にしておくと助かります。

使いどころ

Context は便利ですが、何でも入れる置き場ではありません。テーマ、ログイン中のユーザー、言語のように、アプリのあちこちで同じものを見たい少数のものに向いています。1つの画面の中だけで使う値は、これまでどおり props で足ります。

演習

PriceTag が useContext でテーマを取り、途中の受け渡しを消します。

ヒント

useContext は react から読み込みます

const theme = useContext(ThemeContext); の1行で props の代わりになります

Provider の value={theme} は受け渡しではないので残します

App.tsx
ThemeContext.tsx
プレビュー

できているか

  • カードが3枚並んでいる
  • 3枚とも Context からテーマが届いている
  • 価格が 円 付きで出ている
  • useContext でテーマを取り出している
  • props のバケツリレーが残っていない
エディタを読み込んでいます