【React】useContextの使い方!初心者向けに分かりやすく解説!

React HookのuseContextは何ができるの?

useContextを使うことでデータをグローバルに扱うことができるよ!

目次

Hookとは?

Hook(フック)とはReact 16.8のバージョンで新しくで追加された機能です。

Hookは関数コンポーネントで使うことができる機能で、クラスを書かなくてもstateなどの機能を使えるようになります。

useContextはHookの1つの機能です。

useContextとは?

useContext」は下の階層のコンポーネント(子コンポーネント)とデータの共有を行うときに使うフックです。

通常、親コンポーネントから子コンポーネントにデータを渡すときは、propsを介して行います。
しかし、親から子、そのまた子といったように複数のコンポーネントを介してデータを渡すpropsではデータの渡し方が煩雑になります。

useContextはそのような煩雑なやり取りをせずに、データを渡すことができます。

propsを使ったとき
useContextを使ったとき

useContextの使い方

親コンポーネントと子コンポーネントでの設定が異なるから、
それぞれ解説していくね!

親コンポーネントでの設定

まずはuseContextの機能をインポートします。
インポートしなくても使えますが、 今回はインポートをして使っていきます。

import React, { createContext } from 'react';

インポートしない場合は、createContext()React.createContext()と書きます。

インポートができたらuseContextを使うことができるようになります。

インポートしたcreateContextを使ってcontextを作成します。
作成したcontextの名前は大文字から始まるようにしましょう。

export const CountContext = createContext();

親コンポーネントで作成したCountContextを子コンポーネントで扱えるようにexportをしています。
子コンポーネントではこのCountContextをimportすることになります。

次に作成したcontextオブジェクトを子コンポーネントに渡すための処理を記述します。
少し独特な記述になるので詳しく解説していきます。

まずは作成したCountContextにProviderを用いてCountContext.Providerのように記述します。
そして、続けてvalueの値を指定します。valueの値は子コンポーネントに共有したい値を指定します。
これらの記述は決り文句だと思って下さい。

<CountContext.Provider value={10}>
</ CountContext.Provider>

<CountContext.Provider>で子コンポーネントを囲むことによって、Providerで指定したvalueの値を子コンポーネントで扱えるようになります。

<CountContext.Provider value={10}>
  <子コンポーネント />
</ CountContext.Provider>

まとめると親コンポーネントではこのようになります。

import React, { createContext } from 'react';

// Contextの作成
export const CountContext = createContext();

export const ParentComponent = () => {
  return (
    <div>
      <CountContext.Provider value={10}>
        <ChildComponentC />
      </CountContext.Provider>
    </div>
  );
}

子コンポーネントでの設定

親コンポーネントから渡されたデータを子コンポーネントで扱う方法です。

まずはcontextを使えるように、useContextをインポートします。
こちらもインポートしなくても使えます。

import { useContext } from 'react';

インポートしない場合は、useContext()React.useContext()と書きます。

続いて親コンポーネントで作成したcontextをインポートします。

import { CountContext } from './ParentComponent';

インポートしたものを使ってProviderのvalueで設定した値を受け取ります。
これで子コンポーネントでcountのデータを取得できました。

const count = useContext(CountContext);

まとめると子コンポーネントではこのようになります。

import React, { useContext } from 'react';
import { CountContext } from './ParentComponent';

export const ChildComponentC = () => {
  // 親コンポーネントで設定した値を受け取る
  const count = useContext(CountContext);

  return (
    <div>
      <p>カウント: {count}</p>
    </div>
  )
}

親コンポーネントで渡された値を子コンポーネントで受け取り表示することができました。

親コンポーネントと子コンポーネントでは設定が違うから
注意が必要だね!

useStateを使った方法

useStateと一緒に使うことが多いよ!

useContextはstateを子コンポーネントに渡すことができます。

ReactではuseStateを渡すことが頻繁にあるので、useStateを使った方法を解説していきます。

親コンポーネント

useStatecreateContextをインポートしてcontextを作成します。

import React, { useState, createContext } from 'react';
export const CountContext = createContext();

useStateを作成してProviderのvalueにstateを指定します。
Providerで囲まれた子コンポーネントは親コンポーネントで使っているstateを管理できるようになります。

const [count, setCount] = useState(0);

<CountContext.Provider value={{count, setCount}}>
  <子コンポーネント />
</CountContext.Provider>

まとめるとこのようになります。

import React, { useState, createContext } from 'react';

// Contextの作成
export const CountContext = createContext();

export const ParentComponent = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <CountContext.Provider value={{count, useCount}>
        <ChildComponentC />
      </CountContext.Provider>
    </div>
  );
}

useStateとuseContextを組み合わせて使うことで、コンポーネントをまたいだ状態管理を行うことができます。

子コンポーネント

useContextを使えるようにインポートして、親コンポーネントからcontextをインポートします。

import { useContext } from 'react';
import { CountContext } from './ParentComponent';

変数であるcountと状態を変更する関数であるsetCountの2つを受け取ります。
これで子コンポーネントでもcountとsetCountを使った状態管理ができるようになります。

const { count, setCount } = useContext(CountContext);

まとめるとこのようになります。

import React, { useContext } from 'react';
import { CountContext } from './ParentComponent';

export const ChildComponentC = () => {
  // 親コンポーネントで設定した値を受け取る
  const{ count, setCount } = useContext(CountContext);

  return (
    <div>
      <p>カウント: {count}</p>

    <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  )
}

子コンポーネントでsetCountを使っても、親コンポーネントでsetCountを使っても、同じようにcountに反映させることができます。

stateの管理も簡単にできるんだね!

汎用的に使う方法

コンポーネントの中でcontextを作成して利用していましたが、context自体を別のコンポーネントとして切り出して使う方法です。

別のコンポーネントとすることで汎用的にcontextを使えるようになります。

汎用的なcontextコンポーネント、親コンポーネント、子コンポーネントの3つをそれぞれ解説していきます。

汎用名的に使うcontextコンポーネント

まずはcreateContextuseContextをインポートします。
このcontext内でstateも管理したいのでuseStateもインポートしておきます。

import React, { createContext, useContext, useState } from 'react';

context用のコンポーネントなのでcreateContextでcontextオブジェクトを作成します。

const CountContext = createContext();

作成したstateをProviderのvalueに指定します。
childrenをProviderで囲み、childrenの内容を返すようにします。

const [count, setCount] = useState(0);

<CountContext.Provider value={{ count, setCount }}>
  {children}
</CountContext.Provider>

childrenは特別な意味を持つ名前です。

childrenと記述することで、自身のコンポーネントが呼び出されたとき、呼び出し元のタグの中で記述された内容がchildrenの中に渡ってきます。

まとめるとこのようになります。

import React, { createContext, useContext, useState } from 'react';

const CountContext = createContext();

export const CountProvider = ({ children }) => {
  const [count, setCount] = useState(0);

  return (
    <CountContext.Provider value={{ count, setCount }}>
      {children}
    </CountContext.Provider>
  );
}

親コンポーネント

context用のコンポーネントをインポートします。
CountProviderをインポートしているのでcontext用の機能は親コンポーネントでインポートする必要がなくなります。

import React from 'react';
import { CountProvider } from './providers/CountProvider';

インポートしたCountProviderで子コンポーネントを囲います。

<CountProvider>
  <ChildComponentC />
</CountProvider>

これはCountProviderで囲まれているので以下のようなイメージの記述になっています。

<CountContext.Provider value={{ count, setCount }}>
  <ChildComponentC />
</CountContext.Provider>

まとめるとこのようになります。

import React from 'react';
import { CountProvider } from './providers/CountProvider';

export const ParentComponent = () => {
  return (
    <div>
      <CountProvider>
        <ChildComponentC />
      </CountProvider>
    </div>
  );
}

子コンポーネント

親コンポーネントではなくcontext用のコンポーネントからcontextをインポートします。

import React, { useContext } from 'react';
import { CountContext } from './providers/CountProvider'';

まとめるとこのようになります。

import React, { useContext } from 'react';
import { CountContext } from './providers/CountProvider'';

export const ChildComponentC = () => {
  // context用コンポーネントで設定した値を受け取る
  const{ count, setCount } = useContext(CountContext);

  return (
    <div>
      <p>カウント: {count}</p>

    <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  )
}

context用のコンポーネントを分けることで、
より管理がしやすくなった感じがする!

まとめ

少し独特な記述も出てきたけど、
useContextの使い方について解説したよ!

  • useContextデータの共有を行うときに使うフック
  • データの共有元はcreateContextを使う
  • 作成したcontextオブジェクトを使って〇〇.Providerとして、データを共有したいコンポーネントを囲む
  • 共有したいデータはProviderのvalueに指定する
  • データの共有先ではuseContextを使う

データの共有が便利にできることが分かったよ!
使ってみる!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次