React Hooks の useContext ってどんな機能があるの?
今回は、React Hooks の中でも重要な useContext について、基本的な考え方や使い方、代表的なユースケースまでをわかりやすく解説します。
useContext とは?
useContext とは、コンポーネントツリー内で共有されている値を参照するためのReactフックで、途中のコンポーネントが不要なpropsを受け取らないようにし、propsのバケツリレー(props drilling)を回避するために使われます。
下記のように、あるコンポーネントで使うデータを 親から孫コンポーネントまで渡す場合、
親 → 子 → 孫…とpropsをバケツリレー(props drilling)する必要があり、途中のコンポーネントが不要なpropsを受け取ってしまう問題が発生 します。
App
└─ Parent (props) // 親コンポーネント
└─ Child (props) // 子コンポーネント
└─ GrandChild (props) // 孫コンポーネント 実際にpropsを使う
useContext の基本
useContext は単体では使えず、Contextオブジェクト が必要です
全体の流れ
- createContext で Context を作る
- Provider で値を供給する
- useContext
で値を受け取る
Context を作る
import { createContext } from 'react';
// createContext(初期値);
export const ThemeContext = createContext('light');
useContext で値を受け取る
Provider配下のすべてのコンポーネントが、この Providerのvalue にアクセスできるようになる
import { ThemeContext } from './ThemeContext';
import UseContextPage from './UseContextPage';
function App() {
return (
<ThemeContext.Provider value="dark">
<UseContextPage />
</ThemeContext.Provider>
);
}
import Content from './Content';
export default function UseContextPage() {
return (
<div>
{/* Contentにpropsを渡していないのにthemeを読める */}
<Content />
</div>
);
}
Providerで値を渡す
useContext で Providerのvalue を直接取得できる ※ログに”theme: dark“と表示される
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
export default function Content() {
// Providerのvalue = useContext(Contextオブジェクト);
const theme = useContext(ThemeContext);
console.log('theme:', theme);
return (
<>
<h2>Content</h2>
<p>テーマ: {theme}<p/>
</>
);
}

useContext のその他ユースケース
認証情報(ログイン状態・ユーザー情報)
ログイン しているかどうかを アプリ全体で共有したい
Context を作る
import { createContext } from 'react';
export const AuthContext = createContext({
user: null,
isLogin: false,
login: () => {},
logout: () => {}
});
Provider で状態を管理する
「isLogin: !!user」user がある場合、ログインしていると判定する ※ !! で true or false 判定
import React, { useState } from 'react';
import { AuthContext } from './AuthContext';
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = () => {
setUser({ name: 'Taro', email: 'taro@example.com' });
};
const logout = () => {
setUser(null);
};
const value = {
user,
isLogin: !!user,
login,
logout
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
App全体を Provider で囲む
import { AuthProvider } from './AuthProvider';
import Header from './Header';
import Profile from './Profile';
function App() {
return (
<AuthProvider>
<Header />
<Profile />
</AuthProvider>
);
}
useContext で ログイン状態 を取得
import { useContext } from 'react';
import { AuthContext } from './AuthContext';
export default function Header() {
const { isLogin, login, logout } = useContext(AuthContext);
return (
<header>
{isLogin ? (
<button onClick={logout}>ログアウト</button>
) : (
<button onClick={login}>ログイン</button>
)}
</header>
);
}
useContext で ログイン状態・ユーザー情報の取得・表示
ログインしている場合 は、「ようこそ、Taro さん メール: taro@example.com ログイン中」と表示され、ログアウトしている場合 は、「ログインしてください」と表示される
import { useContext } from 'react';
import { AuthContext } from './AuthContext';
export default function Profile() {
const { user, isLogin } = useContext(AuthContext);
if (!isLogin) {
return <p>ログインしてください</p>;
}
return (
<>
<h2>ようこそ、{user.name} さん</h2>
<p>メール: {user.email}</p>
<h3>ログイン中</h3>
</>
);
}

言語設定(i18n)
- 言語切替ボタン
- 翻訳表示
- 日付フォーマット
export const LanguageContext = createContext({
language: 'ja',
changeLanguage: () => {},
});
const lang = useContext(LanguageContext);
モーダル・ダイアログ制御
- 「どこからでもモーダルを開きたい」
- Header / Button / Page など複数箇所から操作
export const ModalContext = createContext({
isOpen: false,
open: () => {},
close: () => {},
});
const { isOpen, open, close } = useContext(ModalContext);
ユーザー設定・アプリ設定
- 通知ON/OFF
- 表示件数
- レイアウト切替
export const SettingsContext = createContext({
settings: {
notifications: true, // 通知ON/OFF
pageSize: 10, // 表示件数
layout: 'grid', // レイアウト切り替え 'grid' | 'list'
},
updateSettings: () => {},
resetSettings: () => {},
});
const { settings, updateSettings, resetSettings } = useContext(SettingsContext);
まとめ
React Hooks の useContext について、いかがでしたでしょうか?
useContext は、React.js において コンポーネント間で値を共有するための基本的な Hook で、テーマや認証情報、言語設定 など、アプリ全体で共有したい値 を扱うのに向いています。
propsのバケツリレー(props drilling)を避けつつ、シンプルに状態を共有できる点が大きなメリットです。
まずは基本的な使い方をしっかり押さえ、小さな コンポーネント から試しながら、少しずつ useContext に慣れていきましょう。
また公式でも 同じような機能を持つ use を「useContext よりも優先的に使用してください」と記載があるため、下記に use の記事も記載しましたので、use を使うようにしましょう。



コメント