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 で包みます。