JavaScript

ReactのuseContextを理解する

ReactのAPIであるuseContextの使用方法についてまとめます。

useContextとは

useContextは、ReactのHooks APIに最初から組み込まれている関数です。
親コンポーネントで設定した値を、どんなに深い下層コンポーネントでも、propsを用いることなく使用できるようになります。
そのため、propsのバケツリレー(prop drilling)の問題を解消できます。

useContextの使い方

実際にコードでuseContextの使い方を見てみましょう。
ここでは、親コンポーネント(Parent)で設定したuseStateのcountとsetCountを、子コンポーネント(Child)から使用する例を示します。

contextを作成する

最初に、createContextを使用してContextを作成します。
変数名は、公式リファレンスに沿って末尾にContextと付けています。
createContextの引数には、初期値を指定します。
今回は空のオブジェクトを指定しておきます。

import { createContext } from "react";
export const CountContext = createContext({});

親コンポーネントでContextを提供する

親コンポーネントとなるParentコンポーネントを作成し、作成したCountContextを読み込みます。
CountContext.Providerというコンポーネントが使用でき、propsで渡すchildrenをラップします。

valueには、オブジェクトでcountとsetCountを渡し、下層のコンポーネントからcountを変更できるようにします。
これにより、Parentコンポーネントの下層にあるすべてのコンポーネントが、valueに指定した値を参照できます。

import { useState } from "react";
import { CountContext } from "../context/count";

type Props = {
  children: React.ReactNode;
};

function Parent({ children }: Props) {
  const [count, setCount] = useState(0);

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

export default Parent;

子コンポーネントから提供された値を使用する

Parentコンポーネントから提供されたContextを、子コンポーネントのChildコンポーネントから使用します。

CountContextを読み込み、useContextの引数にCountContextを指定します。
戻り値には、Parentコンポーネントの<CountContext.Provider>で指定したvalueを受け取ることができます。

Childコンポーネントでは、Parentコンポーネントが提供したcountやsetCountを使用し、countをインクリメントする処理を記述します。

import { useContext } from "react";
import { CountContext } from "../context/count";

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

  const handleClick = () => {
    setCount(() => count + 1);
  };

  return (
    <>
      <p>count: {count}</p>
      <button onClick={handleClick}>Add Count +1</button>
    </>
  );
}

export default Child;

これで、Parentコンポーネントで提供したcountを、Childコンポーネントからインクリメントする処理が可能になりました。