こんなに簡単なの?React useContextって

ReactのuseContextはコンポーネント間でのデータの受け渡しに関するHookです。useStateやuseReduceと合わせて利用することができます。まず本書では最も基本的な使用方法について説明を行いその後にuseStateを使って利用方法を説明します。本文書を読み終えるとuseContextがどのようなものかを理解することができます。
useContextとは
通常親コンポーネントから子コンポーネントにデータを渡す際は、propsを介して行います。親から子、そのまた子といったように複数のコンポーネントを介してデータを渡すのはpropsでは煩雑になってきます。
ReactのContext APIを利用するとpropsを利用せず下の階層のコンポーネントとデータの共有を行うことができます。
最も簡単な使用例
App.jsファイルを一番親のコンポーネントとして、App.jsファイルに子コンポーネントAをimportし、コンポーネントAにコンポーネントB、コンポーネントBにコンポーネントCをimportした4階層のコンポーネントを作成します。

一番上の親コンポーネントであるApp.jsのファイルの中身は下記のようになります。ComponentA、B、Cについてはcomponentsディレクトリの下に作成していきます。
import React from 'react';
import './App.css';
import ComponentA from './components/ComponentA.js'
function App() {
return (
<div className="App">
<h1>Learn useContext</h1>
<ComponentA/>
</div>
);
}
export default App;
ComponentA
import React from 'react'
import ComponentB from './ComponentB'
const ComponentA = () => {
return (
<div>
<p>Componet A</p>
<ComponentB />
</div>
)
}
export default ComponentA
ComponentB
import React from 'react'
import ComponentC from './ComponentC'
const ComponentB = () => {
return (
<div>
<p>Componet B</p>
<ComponentC />
</div>
)
}
export default ComponentB
ComponentC
import React from 'react'
const ComponentC = () => {
return (
<div>
<p>Componet C</p>
</div>
)
}
export default ComponentC
ブラウザで見ると下記のように表示されます。

App.jsから100という数字をuseContextを利用してComponetCに渡します。
親コンポーネントでの設定
まずContextの作成を行います。Contextの作成はcreateContextで行います。
export const UserCount = React.createContext()
作成したUserCountをexportしているのはContextを利用するComponentCでimportを行うためです。
次はUserCount.Providerコンポーネントで数字を渡したいコンポーネントが入っているComponentAを囲みます。UserCount.Providerのタグの中のvalueに100を設定します。これで親コンポーネントでの設定は完了です。
import React from 'react';
import './App.css';
import ComponentA from './components/ComponentA.js'
export const UserCount = React.createContext()
function App() {
return (
<div className="App">
<h1>Learn useContext</h1>
<UserCount.Provider value={100}>
<ComponentA/>
</UserCount.Provider>
</div>
);
}
export default App;
値を受け取るコンポーネントでの設定
今回はComponentCで値を受け取るのでComponenCのみ設定を行います。他のコンポーネントでも設定方法は同じです。
ComponentCでuseContextを利用するためimportします。また、App.jsでexportしたUserCountもここでimportする必要があります。
import React,{useContext} from 'react'
import { UserCount } from '../App'
useContextとUserCountを使ってvalueで設定した値を取り出し変数countに入れます。
const count = useContext(UserCount)
これでcountをコンポーネントCで利用することができます。
import React,{useContext} from 'react'
import { UserCount } from '../App'
const ComponentC = () => {
const count = useContext(UserCount)
return (
<div>
<p>Componet C</p>
<p>{count}</p>
</div>
)
}
export default ComponentC
ブウウザで確認し、Componet Cの文字列の下に100が表示されれば、App.jsで設定した値がComponet Cに渡されたことになります。

これがuseContextを使った最もシンプルな例です。
useStateと一緒に使う
先程は100という値だけuseContextを利用してComponentCに渡しましたが、今回はuseStateと一緒に利用します。
App.jsでuseStateをimportとして、useStateで設定したcountとsetCountをvalueに設定します。countの初期値は100に設定しています。
import React,{useState} from 'react';
import './App.css';
import ComponentA from './components/ComponentA.js'
export const UserCount = React.createContext()
function App() {
const [count,setCount] = useState(100)
return (
<div className="App">
<h1>Learn useContext</h1>
<UserCount.Provider value={[count, setCount]}>
<ComponentA/>
</UserCount.Provider>
</div>
);
}
export default App;
ComponentCで先程と同様の方法で受け取ります。
import React,{useContext} from 'react'
import { UserCount } from '../App'
const ComponentC = () => {
const [count, setCount]= useContext(UserCount)
return (
<div>
<p>Componet C</p>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}
export default ComponentC
受け取ったsetCountを利用してonClickイベントを利用してcountの値を増やします。

ボタンをクリックするとcount数字が1ずつ増えていくことが確認できます。ただの値だけではなくuseStateの値と関数もuseContextを利用してコンポーネント間で共有できることがわかりました。