Contextを作る

通り道を作らずに配る

前の回で、テーマを4段のバケツリレーで運びました。途中の ItemList と ItemCard は theme を使わないのに、型にも呼び出しにも theme が並びました。

React には、この受け渡しを飛ばす仕組みがあります。Context です。値を入れておく箱を1つ作り、木のどこからでもその箱を覗けるようにします。

入れ物を作る

createContext で箱を作ります。作るのは1回だけなので、部品の外側、それも専用のファイルに置きます。

import { createContext } from "react"; export type Theme = "light" | "dark"; export const ThemeContext = createContext<Theme>("light");

山かっこの <Theme> が「この箱には Theme が入る」という指定です。これを書いておくと、取り出した側でも Theme として扱われます。書かないと、あとで出てくる useContext の戻り値の型が分からなくなります。

丸かっこの "light"既定値です。箱の外側で覗いた部品、つまりあとで説明する Provider に包まれていない部品が受け取る値になります。値が無いことを表したいときは null を既定値にすることもあります。

配る範囲を決める

箱を作っただけでは、まだ誰にも届きません。どこから下に配るかを書きます。それが Provider です。

<ThemeContext.Provider value={theme}> <ItemList items={items} /> </ThemeContext.Provider>

value に入れたものが、この中に描かれる部品すべてに届きます。何段深くても関係ありません。包んだ範囲が配達先だと考えてください。

Provider で包める場所は木の途中でも構いません。fleama では画面全体で同じテーマを使うので、いちばん外側で包みます。

この回はまだ取り出さない

新しく覚えることは1回に1つにします。この回では箱を用意して配る宣言までにして、バケツリレーはそのまま残します。取り出して受け渡しを消すのは次の回です。

演習

ThemeContext を定義して、App の中身を Provider で包みます。

ヒント

App.tsx
ThemeContext.tsx
App.tsx
ThemeContext.tsx
プレビュー

できているか

  • カードが3枚並んでいる
  • 価格に dark のクラスが付いたままになっている
  • スニーカーが並んでいる