【React hooks】噛み砕いて解説してみた~useContext編~

2 min読了の目安(約2500字TECH技術記事

前書き

16.8vで追加された機能であるreact hooksを理解を深めるために体系的にまとめました。

以下、本題です

そもそもContextとは

別コンポーネントに値を動的に渡す方法として、Propsがあると思います。Contextも同じように値を動的に渡すことができます。

Contextの存在意義

多重ネストされたコンポーネントに値を渡すときに、下記のようにバケツリレーになってしまうことが多々あると思います。(コードは公式ドキュメントからコピペしました)

<Page user={user} avatarSize={avatarSize} />
// ... Page コンポーネントは以下をレンダー ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... PageLayout コンポーネントは以下をレンダー ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... NavigationBar コンポーネントは以下をレンダー ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
</Link>

Contextを使うことで、コンポーネントを超えて動的に値を渡すことができます。

実際の使い方(hookなし)

まずはuseContextを使わないパターンを解説していきます。そのほうが理解が深まるからです。(知っているよ!という人は飛ばしてください。)

登場人物

  • createContext()
  • Proveider
  • Consumer

それぞれ軽く説明しておきます。

createContext()

const Context = React.createContext()

この関数でコンテキストオブジェクトが作成されます。このコンテキストオブジェクトは下記のようになっています。

{
  Provider: <>...<>,
  Consumer: <>...<>,
  ...
}

Context.ProviderContext.Consumerのように使われます。実際に見ていきましょう。

Provider

 return (
    <Context.Provider value={resource}>
      <Hoge />
    </Context.Provider>
  )

上記のようにProviderpropsvalueに渡したい値を指定してあげます。

Consumer

const Hoge = () => (
  <Context.Consumer>
    {(resource)=> (
      <h1>{resource.title}</h1>
    )}
  </Context.Consumer>
)

上記のように実際に使いたいコンポーネント(今回はProviderラップしたHogeコンポーネント)でprops.childに対して関数の引数で渡したい値(ここではresource)を入れています。

以上でuseContextを使わないパターンの説明は終了です!

以降からuseContextを使ったパターンの解説をしていきます。

useContextを使う場合

簡潔にお伝えするとConsumerつまり実際に値を呼び出すコンポーネントで使うことができます。useContextを使わない場合は下記のような形ですね。

const Hoge = () => (
  <Context.Consumer>
    {(resource)=> (
      <h1>{resource.title}</h1>
    )}
  </Context.Consumer>
)

useContextを使う場合は下記のようにuseContext()関数の引数にコンテキストオブジェクトを含めてください。

const Hoge = () => {
  const { resource } = useContext(Context)
  
  return (
    <h1>{resource.title}</h1>
  )
}

props.childが不要になったのでスッキリしましたね!

解説は以上です。お疲れ様でした🙇‍♂️

参考記事