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階層のコンポーネントを作成します。

4階層のコンポーネント
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

ブラウザで見ると下記のように表示されます。

4階層のコンポーネントを表示
4階層のコンポーネントを表示

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に渡されたことになります。

コンポーネントCの100が表示
コンポーネントCの100が表示

これが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の値を増やします。

useStateで渡したcountをsetCountで増やす
useStateで渡したcountをsetCountで増やす

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