説明
Reactの公式ドキュメントで、コンテキストの使い道のひとつとして、認証済みユーザ情報を入れておくというのが挙げられている。実際、自分もそのような用途でコンテキストを使いたくなったことがあるので、そういうテイのサンプルコードを書いてみた。
コンテクスト – React
サンプル
この記事のコードでできるもの。
See the Pen
using-contexts-with-react-hooks-and-typescript-about-get-set-and-re-render by napoporitataso (@napoporitataso)
on CodePen.
以下、作り方。
準備
以下コマンドで必要なパッケージをインストール。
この記事を書いた時の各パッケージのバージョンはこんな感じ。
ほか、各種設定ファイルはこんな感じ。適当。
ソースコード
ディレクトリ構成
サンプルコードのディレクトリ構成は以下の通り。
コンテキスト
先に書いたように、ここではログイン中のユーザ情報を共有するためのコンテキストを作る。
コンテキストの値は state として保持しておき、更新は state の setter で行う。そして値と setter をセットで提供するプロバイダを <UserProvider>
として作成する。
ここらへんのファイルの分け方?は色々あると思うんだけど、今のところ自分はこうやることが多い。
それ以外のコード
何の変哲もない index.html
。
何の変哲もない index.tsx
。まだコンテキストは出てこない。
<App>
コンポーネントでは子要素を <UserProvider> ~ </UserProvider>
で挟んでおき、ここ以下で UserContext
にアクセスできるようにする。
コンテキストにアクセスする <UserViewer>
コンポーネントの中身は以下の通り。
useContext(UserContext)
の戻りで UserContext
が提供するユーザ情報とその setter を受け取ることができる。ここではコンテキストから受け取ったユーザ情報を表示するだけでなく、マウントから2秒後に、新しいユーザ情報をコンテキストにセットする。
ところでここまで出てきた <RenderCounter>
コンポーネントは、コンテキストを使ったことで再renderされる範囲を調べるために用意してみた。以下の通り、renderされた回数をラベルと共に表示するだけのもの。
最後に <UserViewer>
に出てきた <Child>
コンポーネント。その名の通りというか、useContext()
を行うコンポーネントの子コンポーネントが再renderされるタイミングを調べるために一応用意した。
実行結果
上記のサンプルコードを全部用意して以下コマンドを実行すると、ブラウザ上で動作確認できる。
結果は以下の通り。
この結果から、UserContext
が保持しているユーザ情報が変化したとき、useContext()
を行っている <UserViewer>
以下の全てのコンポーネントが再renderされることが確認できる。ただし <UserViewer>
にて useMemo()
でメモ化を行った『コンテキスト使用 (メモ化)』カウンタのみは再renderされず、数値が上昇していない。
コンテキストを使うとコンポーネントの上下の繋がりによらず値を受け渡しできて便利だけど、再renderされる範囲が広くなりすぎないように気を付けないとだ。たとえば、何も考えずに全部プロバイダで囲うとかはやめたほうがいい。