1分でわかるReactのcreateContext(useContext)の使い方

createContextとは


ReactのcreateContextはコンポーネントツリー全体にわたってデータを渡すためのメカニズムを提供します。

これにより、親から子、さらにその孫コンポーネントへと順次propsを渡すことなく、必要なコンポーネントが直接データにアクセスできるようになります。

例えば以下のようなoffとonを切り替えるコードがあったとします。

TypeScript
import { useState, ChangeEvent } from 'react'

type Mode = 'off' | 'on'

export default function App() {
  const [mode, setMode] = useState<Mode>('off')

  return (
    <>
      <h1>{mode}</h1>
      <label>
        <input
          type="checkbox"
          checked={mode === 'on'}
          onChange={(e: ChangeEvent<HTMLInputElement>) => {
            setMode(e.target.checked ? 'on' : 'off')
          }}
        />
        mode change
      </label>
    </>
  )
}

Reactでoffとonを切り替え (createContext未使用)

もし、「<h1>{mode}</h1>」をコンポーネント「<Mode />」にする場合、通常はpropsにmodeを渡して以下のようにします。

TypeScript
import { useState, ChangeEvent } from 'react'

type Mode = 'off' | 'on'

export default function App() {
  const [mode, setMode] = useState<Mode>('off')

  return (
    <>
      <Mode mode={mode} />
      <label>
        <input
          type="checkbox"
          checked={mode === 'on'}
          onChange={(e: ChangeEvent<HTMLInputElement>) => {
            setMode(e.target.checked ? 'on' : 'off')
          }}
        />
        mode change
      </label>
    </>
  )
}

function Mode({ mode }: { mode: Mode }) {
  return <h1>{mode}</h1>
}

最初にも述べた通り、createContextを使用するとpropsを渡すことなく、必要なコンポーネントが直接データにアクセスできるようになります。

やり方はcreateContextとuseContextをreactからimportして、createContextでコンテキスト(ModeContext)を作成して、Providerコンポーネントを設定してコンテキストの値を設定し、全体を囲んで、以下のように値を渡します。

コンテキストを使用する際はuseContextフックでコンテキストの値を取得します。

TypeScript
import { createContext, useContext, useState, ChangeEvent } from 'react'

type Mode = 'off' | 'on'
const ModeContext = createContext<Mode | undefined>(undefined)

export default function App() {
  const [mode, setMode] = useState<Mode>('off')
  return (
    <ModeContext.Provider value={mode}>
      <Mode />
      <label>
        <input
          type="checkbox"
          checked={mode === 'on'}
          onChange={(e: ChangeEvent<HTMLInputElement>) => {
            setMode(e.target.checked ? 'on' : 'off')
          }}
        />
        mode change
      </label>
    </ModeContext.Provider>
  )
}

function Mode() {
  const mode = useContext(ModeContext)
  return <h1>{mode}</h1>
}

Reactでoffとonを切り替え (createContext使用)

コンポーネントでpropsで値を渡せないときはcreateContextを使うケースがあるので、使い方を覚えておくと良いです。