Contextとは
まず、Contextについて説明します。Reactで状態をグローバルに共有するための仕組みです。Reactでは通常、props
を使用してコンポーネント間で状態を渡しますが、多くのコンポーネントをまたいで渡す場合、props
を使用すると煩雑になります。そういった時に、Contextを使用します。
Contextを使用すると、Reactコンポーネントツリーのどの部分でも簡単にアクセスできるグローバルな状態を定義できます。より可読性が高まるのです。例えば、
テーマの切り替え
アプリケーション全体で使用するテーマ(ライトモード、ダークモードなど)を管理するために、Contextを使用できます。コンポーネント内でテーマを設定する代わりに、テーマ情報をContextに保存し、アプリケーション全体で使用できるようにします。
認証情報の管理
アプリケーションで認証が必要な場合、ログイン状態やユーザー名などの認証情報をグローバルに管理するために、Contextを使用することができます。
言語設定の切り替え
アプリケーションで多言語をサポートする場合、言語設定をContextに保存して、アプリケーション内の複数のコンポーネントで共有できます。
グローバルな状態の管理
アプリケーション全体で使用する設定やデータをグローバルに管理するために、Contextを使用することができます。アプリケーション内で共有するAPIキー、データベースの接続情報、ユーザーのお気に入りアイテムなどです。
※必ずしも全ての状態をグローバルに管理する必要は無いため、事前に必要な状態を考え、適切に設計することが重要です。
useContextとは
Reactのコンポーネント内でContextを利用するためのHooksです。コンポーネントツリーのどの階層でも同じ状態を共有できます(Contextによって)。Contextオブジェクトを引数に受け取り、現在のコンポーネントのContext値を返します。Context値は、Context.Providerで提供された値と一致します。
以下は、useContext
を使用した例です。
import React, { useContext } from 'react';
// Contextオブジェクトを作成
const MyContext = React.createContext();
function App() {
// Context.Providerで提供された値を取得
const contextValue = useContext(MyContext);
return (
<div>
<h1>{contextValue}</h1>
</div>
);
}
function Parent() {
return (
<MyContext.Provider value="Hello, World!">
<Child />
</MyContext.Provider>
);
}
function Child() {
return <App />;
}
MyContext
というContextオブジェクトを作成し、Parent
コンポーネント内でMyContext.Provider
で提供した値をChild
とApp
コンポーネントで参照するために、useContext
を使用しています。
App
コンポーネント内で、useContext(MyContext)
を使用して、現在のコンポーネントのContext値を取得しています。そして、コンポーネント内でContext値を表示しています。他にも...
テーマの切り替え
import React, { useState, useContext } from 'react';
// テーマのデフォルト値
const defaultTheme = 'light';
// テーマ用のContextを作成する
const ThemeContext = React.createContext(defaultTheme);
// ThemeProviderコンポーネントを作成する
const ThemeProvider = ({ children }) => {
// テーマを保存するためのステートを作成する
const [theme, setTheme] = useState(defaultTheme);
// テーマを切り替える関数を作成する
const toggleTheme = () => {
setTheme(theme === 'light' ? 'dark' : 'light');
};
// ThemeProviderでラップされたコンポーネントをレンダリングする
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
// ThemeContextを使用するコンポーネント
const ThemeComponent = () => {
// ThemeContextからthemeとtoggleThemeを取得する
const { theme, toggleTheme } = useContext(ThemeContext);
// テーマに応じたスタイルを定義する
const styles = {
backgroundColor: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#333' : '#fff',
padding: '1rem',
};
// ボタンをクリックしたときにテーマを切り替える
return (
<div style={styles}>
<h1>{theme} theme</h1>
<button onClick={toggleTheme}>Toggle theme</button>
</div>
);
};
// ThemeProviderでAppコンポーネントをラップする
const App = () => {
return (
<ThemeProvider>
<ThemeComponent />
</ThemeProvider>
);
};
export default App;
ThemeProvider
コンポーネントでテーマを定義し、ThemeComponent
コンポーネントでテーマを使用します。ThemeProvider
では、useState
フックを使用してテーマのステートを作成し、toggleTheme
関数(クリックイベント。現在のテーマを反転させます)を定義します。
ThemeProvider
コンポーネントで、テーマとtoggleTheme
関数をラップします。ThemeComponent
でuseContext
フックを使用し、ThemeContext
からテーマとtoggleTheme
関数を取得し、テーマに応じたスタイルを定義します。ThemeProvider
でThemeComponent
をラップすることで、ThemeContext
を使用できるようになります。
useContextを複数使用
import React, { useContext } from 'react';
// コンテキストを作成
const ThemeContext = React.createContext('light');
const UserContext = React.createContext('Guest');
function App() {
// useContextフックを使用して、コンテキストを取得
const theme = useContext(ThemeContext);
const user = useContext(UserContext);
return (
<div>
<p>Theme: {theme}</p>
<p>User: {user}</p>
</div>
);
}
function ParentComponent() {
return (
<ThemeContext.Provider value="dark">
<UserContext.Provider value="John">
<App />
</UserContext.Provider>
</ThemeContext.Provider>
);
}
ThemeContext
とUserContext
の2つのコンテキストを作成しています。
App
コンポーネントの中で、それぞれのコンテキストをuseContext
フックを使って取得しています。コンテキスト値の設定は、ParentComponent
のThemeContext.Provider
とUserContext.Provider
です。