【React】useContexでContextを参照する手順

JavaScript

React ContextはReduxのようにグローバルなデータの定義と参照ができるReactのAPIです。
React Contextには「Reduxなしでグローバルなデータの定義ができる」「Props drillingと呼ばれる、いわゆるpropsのバケツリレー問題を解決できる」などのメリットがあります。

Contextを作成し、useContextで値を参照するための手順は以下の通りです。

  1. Providerコンポーネントを作成する
  2. ProviderコンポーネントでContext利用対象のコンポーネントを囲む
  3. Contextをコンポーネントから呼び出す

以下では具体例を交えながら各手順について紹介します。

Providerコンポーネントを作成する

Providerコンポーネントでやることは以下の通りです。

  • createContextでContextを作成する
  • createContextで作成されたContextをexportし、他のコンポーネントから参照できるようにする
  • Providerコンポーネントのvalueプロパティに他のコンポーネントから参照したい値をセットする

具体例は以下の通りです。

src/components/shared/ExampleProvider.tsx

import React, { createContext, FC, ReactNode } from "react";

type Props = {
  children: ReactNode;
};

const defaultMessage = "Hi";

export const ExampleContext = createContext<string>(defaultMessage);

export const ExampleProvider: FC<Props> = ({ children }) => {
  return (
    <ExampleContext.Provider value={defaultMessage}>
      {children}
    </ExampleContext.Provider>
  );
};

createContext<string><string>はジェネリックメソッド(ジェネリック関数)と呼ばれるものです。今回の場合はジェネリックメソッドを利用してContextの型をString型に指定しています。

ジェネリクスの詳細解説は【TypeScript】ジェネリクス(Generics)入門。ジェネリクスの種類と利用例で紹介しています。

ProviderコンポーネントでContext利用対象のコンポーネントを囲む

今回の場合ですと<ExampleProvider>でコンポーネントを囲みます。
任意のコンポーネントでContextを利用したい場合は_app.tsxにProviderコンポーネントを追記します。

_app.tsx

import "../../styles/globals.css";
import type { AppProps } from "next/app";
import { ExampleProvider } from 'src/components/shared/ExampleProvider';

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ExampleProvider>
      <Component {...pageProps} />
    </ExampleProvider>
  );
}

export default MyApp;

Contextをコンポーネントから呼び出す

Contextの呼び出し方法は以下の通りです。

  • Providerコンポーネントで作成されたContextをimportする
  • importしたContextをuseContextの引数にする

useContextの戻り値がProviderコンポーネントのvalueプロパティの値になります。

src/pages/index.tsx

import type { NextPage } from "next";
import { ExampleContext } from "src/components/shared/ExampleProvider";
import { useContext } from "react";

const Home: NextPage = () => {
  const message = useContext(ExampleContext);
  return <>{message}</>; // 画面には"Hi"と表示される
};

export default Home;

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

参考記事