React Context API を使う簡単な例
ここでは Provider を使ってコンテキストにデータを置いて、Consumer でコンテキストからデータを取得するだけの簡単な例を示します。
ここで作成したコードを元にして変更を加えて、少しずつ実践的なコードにしていきます。出来上がりの形を先に知りたい人は「カスタムフックで Context をエクスポートしないようリファクタリングする」をみてください。
Provider や Consumer の概要については「React Context とは?」をみてください。
ここで作るサンプルプログラムでは、次のように果物 (Fruits) のリストを表示します。
ここで果物リストのデータソースは、次のような配列にあるとします。
const fruits = ['Apple', 'Orange', 'Banana'];
この配列データをコンテキストに置いて取り出す、ということをやってみましょう。
React プロジェクトの作成
まずは基本となるプログラムを作成します。
npx create-react-app test-context-1
これで作成されたソースコードを編集します。
Context の作成と Provider の実装
index.jsを編集します。ここでコンテキストを作成し、さらにプロバイダを実装しましょう。
Provider のポイントは2点あります。
ひとつはコンテキストのスコープを決めることです。スコープを決めるためには、プロバイダのタグでスコープを囲みます。
そしてもうひとつのポイントは、コンテキストにデータを置くことです。コンテキストにデータを置くには、プロバイダのvalueプロパティにデータをセットします。
import React, { createContext } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
const fruits = ['Apple', 'Orange', 'Banana'];
export const FruitContext = createContext();
FruitContext.displayName = "FruitContext";
ReactDOM.render(
<React.StrictMode>
<FruitContext.Provider value={{ fruits }}>
<App />
</FruitContext.Provider>
</React.StrictMode>,
document.getElementById('root')
);
ここではまず 6 行目で、データソースとなる配列を作成しています。
続いて 7 行目で、React で定義されているcreateContext()関数を使って、コンテキストオブジェクトFruitContextを作成しています。createContext は 1 行目で import しています。
コンテキストに紐づいた Provider と Consumer は、コンテキストのプロパティとして取得できます。
12 行目と 14 行目で、FruitContext.Providerで Appを囲んでいます。 これによって、このコンテキストのスコープ (適用範囲) を決めています。
Appをプロバイダで囲んでいるので、コンテキストのスコープはコンポーネントツリーにおける App 以下全てになります。
12 行目ではさらに、FuitContext.Providerのvalueプロパティに、配列データfruitsを渡しています。これによって、このコンテキストの FruitContext.Consumerにて fruitsが受け取れるようになります。
{fruits}はfruitsという名前のプロパティに、 変数fruitsの値 (ここでは配列) をセットしたオブジェクトになります。つまり value={{value}} としたということは、 value プロパティに次のようなオブジェクトを渡したことになります。
{
fruits: ['Apple', 'Orange', 'Banana']
}
これはショートハンドプロパティというシンタックスです。「JavaScript のショートハンドプロパティ」も参考にしてください。
このほか、index.cssでは、body の margin を変更しておきます。
body {
margin: 1rem;
font-family: -apple-system, BlinkMacSystemFont, ...
これでプロバイダができました。
Consumer の実装
App.js に Consumer を実装します。
もう一度出来上がりは次の画面をみてみましょう。
Fruits という見出しを h1 タグで作り、それに続いて ul タグでリストを作ります。
Consumer を次のようにします。
import React from 'react';
import { FruitContext } from './index';
import './App.css';
function App() {
return (
<FruitContext.Consumer>
{(value) => {
const { fruits } = value;
return (
<>
<h1>Fruits</h1>
<ul>
{fruits.map((fruit, i) => (
<li key={i}>{fruit}</li>
))}
</ul>
</>
);
}}
</FruitContext.Consumer>
);
}
export default App;
2 行目で index.js から FruitContext をインポートします。Consumer はコンテキストのプロパティとして取得できます。
7 行目から 21 行目で Consumer 要素を実装しています。
8 行目からのアロー関数に、プロバイダの value プロパティに渡した value が渡されます。9 行目で分割代入を使って、value から fruits を取り出しています。この中身は ['Apple', 'Orange', 'Banana'] となります。
11 行目と 18 行目の <> と </> の組み合わせは、 <React.Fragament> と </React.Fragament> の短縮形表記です。
14-15 行目で配列の map 関数を使って、リストアイテム li を生成しています。
これで Consumer も実装できました。
npm start
として、開発サーバーをスタートして、ブラウザから http://localhost:3000/ にアクセスすれば動作が確認できるはずです。
次のステップは?
これで、コンテキストにデータをセットして、取得することはできました。
次の記事「useState フックを用いてステートにデータを置く」ではこのプログラムを変更して、配列データをステートに保存します。