icon

Blog

[React] useContextの使い方

2020/08/01

Reactの使い方シリーズ(新)

ReactのContextをhooksとして扱うuseContextをどうやって使うのかメモ。


Context

下位のコンポーネントにPropsではなくContextを経由してデータを渡すことができる。コンテキストって読みたくなるけどReactのドキュメントではコンテクスト。

コンテクスト - React

使い方

React.createContextで作成したContextをProviderで任意のコンポーネントツリーから使用できる

SettingsをContextとして共有する.tsx

// React.createContextでContextを作る
// changeThemeなどの振る舞いもここで定義可能
const SettingsContext = React.createContext<{
  theme: "light" | "dark"
  language: "ja"
}>({ theme: "light", language: "ja" })

// React.useContextでcontextを取得する
const useSettingsContext = () => {
  // そのままuseContextを各コンポーネントから使うだけでは値の変化を追えない
  const context = React.useContext(SettingsContext)
  if (!context)
    throw new Error("useSettingsContext must be used within SettingsProvider.")
  return context
}

// Context.Providerを使ったコンポーネントでProviderを作り、Contextで共有するvalueを使う
// 直接SettingsContext.Providerを使う方法でもよいが、この方法では初期値をSettingsProviderで設定している
const SettingsProvider = (props) => {
  // パフォーマンス向上のためメモ化しておく
  const value = React.useMemo(() => ({
    theme: "dark",
    language: "ja"
  }))
  return <SettingsContext.Provider value={value} {...props} />
}

const Settings = () => {
  // SettingsProviderの中のコンポーネントではuseSettingsContextで設定値を取得できる
  const settings = useSettingsContext()
  const lang = settings.language
  const theme = settings.theme
  return (
    <>
      <p>{lang}</p>
      <p>{theme}</p>
    </>
  )
}

const App = () => {
  return (
    <SettingsProvider>
      <h1>React useContext demo</h1>
      <Settings />
    </SettingsProvider>
  )
}

ReactDOM.render(<App />, document.querySelector(".app"))