<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>http://mochiuwiki.e2.valueserver.jp/index.php?action=history&amp;feed=atom&amp;title=React%E3%81%AE%E5%9F%BA%E7%A4%8E_-_useContext</id>
	<title>Reactの基礎 - useContext - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="http://mochiuwiki.e2.valueserver.jp/index.php?action=history&amp;feed=atom&amp;title=React%E3%81%AE%E5%9F%BA%E7%A4%8E_-_useContext"/>
	<link rel="alternate" type="text/html" href="http://mochiuwiki.e2.valueserver.jp/index.php?title=React%E3%81%AE%E5%9F%BA%E7%A4%8E_-_useContext&amp;action=history"/>
	<updated>2026-07-01T12:05:28Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://mochiuwiki.e2.valueserver.jp/index.php?title=React%E3%81%AE%E5%9F%BA%E7%A4%8E_-_useContext&amp;diff=14544&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == &lt;code&gt;useContext&lt;/code&gt; は、コンポーネントツリーを通じてデータを受け渡す仕組みである &lt;u&gt;Context API&lt;/u&gt; から値を取得するためのHookである。&lt;br&gt; &lt;br&gt; Reactアプリケーションでは、親から子へとデータをPropsで渡していく構造が基本となる。&lt;br&gt; しかし、コンポーネントの階層が深くなると、途中のコンポーネントがそのデータを使用しないにもかか…」</title>
		<link rel="alternate" type="text/html" href="http://mochiuwiki.e2.valueserver.jp/index.php?title=React%E3%81%AE%E5%9F%BA%E7%A4%8E_-_useContext&amp;diff=14544&amp;oldid=prev"/>
		<updated>2026-03-06T21:43:35Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == &amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; は、コンポーネントツリーを通じてデータを受け渡す仕組みである &amp;lt;u&amp;gt;Context API&amp;lt;/u&amp;gt; から値を取得するためのHookである。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; Reactアプリケーションでは、親から子へとデータをPropsで渡していく構造が基本となる。&amp;lt;br&amp;gt; しかし、コンポーネントの階層が深くなると、途中のコンポーネントがそのデータを使用しないにもかか…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; は、コンポーネントツリーを通じてデータを受け渡す仕組みである &amp;lt;u&amp;gt;Context API&amp;lt;/u&amp;gt; から値を取得するためのHookである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Reactアプリケーションでは、親から子へとデータをPropsで渡していく構造が基本となる。&amp;lt;br&amp;gt;&lt;br /&gt;
しかし、コンポーネントの階層が深くなると、途中のコンポーネントがそのデータを使用しないにもかかわらず、下位のコンポーネントに渡すためだけにPropsを受け取り続ける &amp;lt;u&amp;gt;Prop Drilling&amp;lt;/u&amp;gt; という問題が発生する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; はこの問題を解消し、任意の階層からContextの値に直接アクセスできるようにする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Context APIは、以下に示す3つの要素で構成される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Context APIの構成要素&lt;br /&gt;
! 要素 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;createContext&amp;lt;/code&amp;gt; || コンテキストオブジェクトを作成する。&amp;lt;br&amp;gt;デフォルト値を引数に取る。&lt;br /&gt;
|-&lt;br /&gt;
| Provider || 子コンポーネントに値を提供する。&amp;lt;br&amp;gt;値を変更すると、全ての購読コンポーネントが再レンダリングされる。&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; || Providerが提供する値をコンポーネントから取得する。&amp;lt;br&amp;gt;最も近い上位のProviderの値を返す。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
React 19では、&amp;lt;code&amp;gt;&amp;amp;lt;MyContext.Provider value={...}&amp;amp;gt;&amp;lt;/code&amp;gt; という構文に加えて、&amp;lt;code&amp;gt;&amp;amp;lt;MyContext value={...}&amp;amp;gt;&amp;lt;/code&amp;gt; と記述する &amp;lt;u&amp;gt;Context as Provider&amp;lt;/u&amp;gt; パターンが導入された。&amp;lt;br&amp;gt;&lt;br /&gt;
また、条件分岐やループ内でも呼び出せる &amp;lt;code&amp;gt;use()&amp;lt;/code&amp;gt; Hookが追加され、より柔軟なContext利用が可能になった。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Context APIの基本 ==&lt;br /&gt;
Context APIを構成する3つの要素の使い方を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== createContext ====&lt;br /&gt;
&amp;lt;code&amp;gt;createContext&amp;lt;/code&amp;gt; 関数を使用してコンテキストオブジェクトを作成する。&amp;lt;br&amp;gt;&lt;br /&gt;
引数にはProviderが存在しない場合に返されるデフォルト値を指定する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // デフォルト値を指定してコンテキストを作成する&lt;br /&gt;
 const ThemeContext = createContext(&amp;#039;light&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
 // デフォルト値にオブジェクトを指定することもできる&lt;br /&gt;
 const UserContext = createContext({ name: &amp;#039;未ログイン&amp;#039;, isLoggedIn: false });&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
デフォルト値は、コンポーネントツリーのどこにも対応するProviderが存在しない場合にのみ使用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
TypeScriptでの型安全なパターンについては、後述の[[#TypeScriptでの型定義]]セクションを参照すること。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Provider ====&lt;br /&gt;
Providerは、子孫コンポーネントにContextの値を提供するコンポーネントである。&amp;lt;br&amp;gt;&lt;br /&gt;
Providerで囲まれたコンポーネントは、&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; を通じて値にアクセスできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
React 18以前では、必ず &amp;lt;code&amp;gt;MyContext.Provider&amp;lt;/code&amp;gt; という形式で記述する必要があった。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* React 18以前のProvider構文&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeContext.Provider value=&amp;quot;dark&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;Header /&amp;gt;&lt;br /&gt;
          &amp;lt;Main /&amp;gt;&lt;br /&gt;
       &amp;lt;/ThemeContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* React 19以降のProvider構文 (Context as Provider)&lt;br /&gt;
*: React 19以降では、コンテキストオブジェクト自体をProviderとして直接使用できる。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeContext value=&amp;quot;dark&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;Header /&amp;gt;&lt;br /&gt;
          &amp;lt;Main /&amp;gt;&lt;br /&gt;
       &amp;lt;/ThemeContext&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== useContext ====&lt;br /&gt;
&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; Hookは、最も近い上位のProviderが提供する値を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { useContext } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 function Header() {&lt;br /&gt;
    // 最も近いThemeContext.Providerのvalueを取得する&lt;br /&gt;
    const theme = useContext(ThemeContext);&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;header className={theme === &amp;#039;dark&amp;#039; ? &amp;#039;header-dark&amp;#039; : &amp;#039;header-light&amp;#039;}&amp;gt;&lt;br /&gt;
          サイトヘッダ&lt;br /&gt;
       &amp;lt;/header&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Providerがネストしている場合、&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; は呼び出し元のコンポーネントから最も近い (最も内側の) Providerの値を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TypeScriptでの型定義 ==&lt;br /&gt;
TypeScriptを使用する場合、Contextの型を明示的に定義することで型安全なアクセスが可能になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Contextの型定義 ====&lt;br /&gt;
デフォルト値に &amp;lt;u&amp;gt;undefined&amp;lt;/u&amp;gt; を使用するパターンが推奨される。&amp;lt;br&amp;gt;&lt;br /&gt;
このパターンにより、Providerの外でContextを使用した場合にTypeScriptが警告を出すようになる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useState } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 interface ThemeContextValue {&lt;br /&gt;
    theme: &amp;#039;light&amp;#039; | &amp;#039;dark&amp;#039;;&lt;br /&gt;
    setTheme: (theme: &amp;#039;light&amp;#039; | &amp;#039;dark&amp;#039;) =&amp;gt; void;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // デフォルト値をundefinedにして型パラメータを指定する&lt;br /&gt;
 const ThemeContext = createContext&amp;lt;ThemeContextValue | undefined&amp;gt;(undefined);&lt;br /&gt;
&lt;br /&gt;
 function ThemeProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [theme, setTheme] = useState&amp;lt;&amp;#039;light&amp;#039; | &amp;#039;dark&amp;#039;&amp;gt;(&amp;#039;light&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeContext.Provider value={{ theme, setTheme }}&amp;gt;&lt;br /&gt;
          {children}&lt;br /&gt;
       &amp;lt;/ThemeContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== カスタムHookによる型安全なアクセス ====&lt;br /&gt;
&amp;lt;code&amp;gt;createContext&amp;amp;lt;T | undefined&amp;amp;gt;(undefined)&amp;lt;/code&amp;gt; パターンと組み合わせて、カスタムHookを作成することでより安全にContextを利用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
カスタムHookの中でundefinedチェックを行うことにより、Provider未配置時のエラーを早期に検出できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { useContext } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // ThemeContext用のカスタムHook&lt;br /&gt;
 function useTheme(): ThemeContextValue {&lt;br /&gt;
    const context = useContext(ThemeContext);&lt;br /&gt;
    if (context === undefined) {&lt;br /&gt;
       throw new Error(&amp;#039;useTheme は ThemeProvider の内側で使用してください&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
    return context;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 使用側のコンポーネント&lt;br /&gt;
 function ThemeToggleButton() {&lt;br /&gt;
    const { theme, setTheme } = useTheme();&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;button onClick={() =&amp;gt; setTheme(theme === &amp;#039;light&amp;#039; ? &amp;#039;dark&amp;#039; : &amp;#039;light&amp;#039;)}&amp;gt;&lt;br /&gt;
          現在のテーマ: {theme}&lt;br /&gt;
       &amp;lt;/button&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
このパターンを使用することにより、以下に示すメリットが得られる。&amp;lt;br&amp;gt;&lt;br /&gt;
* 型安全性&lt;br /&gt;
*: 戻り値が常に &amp;lt;code&amp;gt;ThemeContextValue&amp;lt;/code&amp;gt; 型であることが保証される。&lt;br /&gt;
* エラーの早期検出&lt;br /&gt;
*: Provider未配置の場合に明確なエラーメッセージが表示される。&lt;br /&gt;
* 利便性&lt;br /&gt;
*: 使用側で毎回 &amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; とContextオブジェクトをimportする必要がなくなる。&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== React 19でのContextの変更 ==&lt;br /&gt;
React 19では、Contextに関する構文と機能が拡張された。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Context as Providerパターン ====&lt;br /&gt;
React 19以降では、コンテキストオブジェクトをProviderとして直接使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、&amp;lt;code&amp;gt;MyContext.Provider&amp;lt;/code&amp;gt; という冗長な記述が不要になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useState } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const ThemeContext = createContext&amp;lt;&amp;#039;light&amp;#039; | &amp;#039;dark&amp;#039;&amp;gt;(&amp;#039;light&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
 function App() {&lt;br /&gt;
    const [theme, setTheme] = useState&amp;lt;&amp;#039;light&amp;#039; | &amp;#039;dark&amp;#039;&amp;gt;(&amp;#039;light&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       // React 19: &amp;lt;ThemeContext.Provider&amp;gt; の代わりに &amp;lt;ThemeContext&amp;gt; を直接使用できる&lt;br /&gt;
       &amp;lt;ThemeContext value={theme}&amp;gt;&lt;br /&gt;
          &amp;lt;Header /&amp;gt;&lt;br /&gt;
          &amp;lt;Main /&amp;gt;&lt;br /&gt;
       &amp;lt;/ThemeContext&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== use() Hook ====&lt;br /&gt;
&amp;lt;u&amp;gt;React 19では、&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; の改良版として &amp;lt;code&amp;gt;use()&amp;lt;/code&amp;gt; Hookが追加された。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;code&amp;gt;use()&amp;lt;/code&amp;gt; の最大の特徴は、条件分岐やループの内側でも呼び出せる点である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { use } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 function ThemeDisplay({ showTheme }: { showTheme: boolean }) {&lt;br /&gt;
    // use()は、if文の内側でも呼び出せる (通常のHookはこれができない)&lt;br /&gt;
    if (showTheme) {&lt;br /&gt;
       const theme = use(ThemeContext);&lt;br /&gt;
       return &amp;lt;p&amp;gt;現在のテーマ: {theme}&amp;lt;/p&amp;gt;;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return &amp;lt;p&amp;gt;テーマ非表示&amp;lt;/p&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
下表に、&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;use()&amp;lt;/code&amp;gt; の比較を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ useContext と use() の比較&lt;br /&gt;
! 項目 !! useContext !! use()&lt;br /&gt;
|-&lt;br /&gt;
| React バージョン || React 16.8以降 || React 19以降&lt;br /&gt;
|-&lt;br /&gt;
| 条件分岐内での呼び出し || 不可 || 可能&lt;br /&gt;
|-&lt;br /&gt;
| ループ内での呼び出し || 不可 || 可能&lt;br /&gt;
|-&lt;br /&gt;
| Promiseの受け取り || 不可 || 可能 (Suspenseと組み合わせて使用)&lt;br /&gt;
|-&lt;br /&gt;
| 使用場所 || 関数コンポーネントのトップレベルのみ || より柔軟な場所で使用可能&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== サンプルコード ==&lt;br /&gt;
実務での使用頻度が高いContextのパターンを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== テーマ切替 ====&lt;br /&gt;
ライト/ダークモードのようなテーマ設定を、アプリケーション全体で共有するパターンである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useContext, useState } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 type Theme = &amp;#039;light&amp;#039; | &amp;#039;dark&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 interface ThemeContextValue {&lt;br /&gt;
    theme: Theme;&lt;br /&gt;
    resolvedTheme: Theme;&lt;br /&gt;
    setTheme: (theme: Theme) =&amp;gt; void;&lt;br /&gt;
    toggleTheme: () =&amp;gt; void;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 const ThemeContext = createContext&amp;lt;ThemeContextValue | undefined&amp;gt;(undefined);&lt;br /&gt;
 &lt;br /&gt;
 export function ThemeProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [theme, setTheme] = useState&amp;lt;Theme&amp;gt;(&amp;#039;light&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
    const toggleTheme = () =&amp;gt; {&lt;br /&gt;
       setTheme(prev =&amp;gt; prev === &amp;#039;light&amp;#039; ? &amp;#039;dark&amp;#039; : &amp;#039;light&amp;#039;);&lt;br /&gt;
    };&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeContext.Provider value={{ theme, resolvedTheme: theme, setTheme, toggleTheme }}&amp;gt;&lt;br /&gt;
          {children}&lt;br /&gt;
       &amp;lt;/ThemeContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export function useTheme(): ThemeContextValue {&lt;br /&gt;
    const context = useContext(ThemeContext);&lt;br /&gt;
    if (!context) throw new Error(&amp;#039;useTheme は ThemeProvider の内側で使用してください&amp;#039;);&lt;br /&gt;
    return context;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 使用例&lt;br /&gt;
 function ThemeToggleButton() {&lt;br /&gt;
    const { theme, toggleTheme } = useTheme();&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;button onClick={toggleTheme}&amp;gt;&lt;br /&gt;
          {theme === &amp;#039;light&amp;#039; ? &amp;#039;ダークモードに切替&amp;#039; : &amp;#039;ライトモードに切替&amp;#039;}&lt;br /&gt;
       &amp;lt;/button&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 認証情報管理 ====&lt;br /&gt;
ログインユーザの情報をアプリケーション全体で共有するパターンである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useContext, useState } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 interface User {&lt;br /&gt;
    id: string;&lt;br /&gt;
    name: string;&lt;br /&gt;
    email: string;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 interface AuthContextValue {&lt;br /&gt;
    user: User | null;&lt;br /&gt;
    isLoading: boolean;&lt;br /&gt;
    login: (email: string, password: string) =&amp;gt; Promise&amp;lt;void&amp;gt;;&lt;br /&gt;
    logout: () =&amp;gt; void;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 const AuthContext = createContext&amp;lt;AuthContextValue | undefined&amp;gt;(undefined);&lt;br /&gt;
 &lt;br /&gt;
 export function AuthProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [user, setUser] = useState&amp;lt;User | null&amp;gt;(null);&lt;br /&gt;
    const [isLoading, setIsLoading] = useState(false);&lt;br /&gt;
 &lt;br /&gt;
    const login = async (email: string, password: string) =&amp;gt; {&lt;br /&gt;
       setIsLoading(true);&lt;br /&gt;
       try {&lt;br /&gt;
          // 認証APIを呼び出す処理&lt;br /&gt;
          const userData = await fetchUser(email, password);&lt;br /&gt;
          setUser(userData);&lt;br /&gt;
       }&lt;br /&gt;
       finally {&lt;br /&gt;
          setIsLoading(false);&lt;br /&gt;
       }&lt;br /&gt;
    };&lt;br /&gt;
 &lt;br /&gt;
    const logout = () =&amp;gt; {&lt;br /&gt;
       setUser(null);&lt;br /&gt;
    };&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;AuthContext.Provider value={{ user, isLoading, login, logout }}&amp;gt;&lt;br /&gt;
          {children}&lt;br /&gt;
       &amp;lt;/AuthContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export function useAuth(): AuthContextValue {&lt;br /&gt;
    const context = useContext(AuthContext);&lt;br /&gt;
    if (!context) throw new Error(&amp;#039;useAuth は AuthProvider の内側で使用してください&amp;#039;);&lt;br /&gt;
    return context;&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 言語設定 (i18n) ====&lt;br /&gt;
アプリケーションの表示言語をグローバルに管理するパターンである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useContext, useState, useCallback } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 type Locale = &amp;#039;ja&amp;#039; | &amp;#039;en&amp;#039; | &amp;#039;zh&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 type TranslationKey = &amp;#039;greeting&amp;#039; | &amp;#039;farewell&amp;#039; | &amp;#039;submit&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const translations: Record&amp;lt;Locale, Record&amp;lt;TranslationKey, string&amp;gt;&amp;gt; = {&lt;br /&gt;
    ja: { greeting: &amp;#039;こんにちは&amp;#039;, farewell: &amp;#039;さようなら&amp;#039;, submit: &amp;#039;送信&amp;#039; },&lt;br /&gt;
    en: { greeting: &amp;#039;Hello&amp;#039;, farewell: &amp;#039;Goodbye&amp;#039;, submit: &amp;#039;Submit&amp;#039; },&lt;br /&gt;
    zh: { greeting: &amp;#039;你好&amp;#039;, farewell: &amp;#039;再见&amp;#039;, submit: &amp;#039;提交&amp;#039; },&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 interface I18nContextValue {&lt;br /&gt;
    locale: Locale;&lt;br /&gt;
    setLocale: (locale: Locale) =&amp;gt; void;&lt;br /&gt;
    t: (key: TranslationKey) =&amp;gt; string;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 const I18nContext = createContext&amp;lt;I18nContextValue | undefined&amp;gt;(undefined);&lt;br /&gt;
 &lt;br /&gt;
 export function I18nProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [locale, setLocale] = useState&amp;lt;Locale&amp;gt;(&amp;#039;ja&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
    const t = useCallback((key: TranslationKey): string =&amp;gt; {&lt;br /&gt;
       return translations[locale][key];&lt;br /&gt;
    }, [locale]);&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;I18nContext.Provider value={{ locale, setLocale, t }}&amp;gt;&lt;br /&gt;
          {children}&lt;br /&gt;
       &amp;lt;/I18nContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export function useI18n(): I18nContextValue {&lt;br /&gt;
    const context = useContext(I18nContext);&lt;br /&gt;
    if (!context) throw new Error(&amp;#039;useI18n は I18nProvider の内側で使用してください&amp;#039;);&lt;br /&gt;
    return context;&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Providerのネスト ==&lt;br /&gt;
複数のContextを組み合わせる場合は、Providerをネストして使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
アプリケーションが成長すると、多数のProviderがネストされて記述が複雑になる問題が生じる。&amp;lt;br&amp;gt;&lt;br /&gt;
これを解消するためのパターンとして、CombinedProviderパターンとComposeProvidersパターンがある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // 複数のProviderを1つにまとめるCombinedProviderパターン&lt;br /&gt;
 function CombinedProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeProvider&amp;gt;&lt;br /&gt;
          &amp;lt;AuthProvider&amp;gt;&lt;br /&gt;
             &amp;lt;I18nProvider&amp;gt;&lt;br /&gt;
                {children}&lt;br /&gt;
             &amp;lt;/I18nProvider&amp;gt;&lt;br /&gt;
          &amp;lt;/AuthProvider&amp;gt;&lt;br /&gt;
       &amp;lt;/ThemeProvider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // App.tsxでの使用&lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;CombinedProvider&amp;gt;&lt;br /&gt;
          &amp;lt;Router&amp;gt;&lt;br /&gt;
             &amp;lt;AppContent /&amp;gt;&lt;br /&gt;
          &amp;lt;/Router&amp;gt;&lt;br /&gt;
       &amp;lt;/CombinedProvider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
さらに汎用的なアプローチとして、Providerの配列を動的に合成するComposeProvidersパターンがある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 type ProviderComponent = ({ children }: { children: React.ReactNode }) =&amp;gt; JSX.Element;&lt;br /&gt;
 &lt;br /&gt;
 function composeProviders(...providers: ProviderComponent[]) {&lt;br /&gt;
    return ({ children }: { children: React.ReactNode }) =&amp;gt; {&lt;br /&gt;
       return providers.reduceRight(&lt;br /&gt;
          (acc, Provider) =&amp;gt; &amp;lt;Provider&amp;gt;{acc}&amp;lt;/Provider&amp;gt;,&lt;br /&gt;
          children as JSX.Element&lt;br /&gt;
       );&lt;br /&gt;
    };&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 使用例&lt;br /&gt;
 const AppProviders = composeProviders(ThemeProvider, AuthProvider, I18nProvider);&lt;br /&gt;
 &lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;AppProviders&amp;gt;&lt;br /&gt;
          &amp;lt;AppContent /&amp;gt;&lt;br /&gt;
       &amp;lt;/AppProviders&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== パフォーマンスの考慮事項 ==&lt;br /&gt;
Contextを使用する場合は、パフォーマンスへの影響を考慮する必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Context値変更時の再レンダリング ====&lt;br /&gt;
Contextの値が変更されると、そのContextを購読している全てのコンポーネントが再レンダリングされる。&amp;lt;br&amp;gt;&lt;br /&gt;
オブジェクトや配列をContext値として渡す場合、参照が毎回変わるため不必要な再レンダリングが発生しやすい。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // 問題のあるパターン : レンダリングのたびに新しいオブジェクトが作成される&lt;br /&gt;
 function ProblematicProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [user, setUser] = useState&amp;lt;User | null&amp;gt;(null);&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       // value に毎回新しいオブジェクトが渡されるため、不要な再レンダリングが起きる&lt;br /&gt;
       &amp;lt;UserContext.Provider value={{ user, setUser }}&amp;gt;&lt;br /&gt;
          {children}&lt;br /&gt;
       &amp;lt;/UserContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== useMemoによる最適化 ====&lt;br /&gt;
&amp;lt;code&amp;gt;useMemo&amp;lt;/code&amp;gt; を使用してContext値をメモ化することにより、不必要な再レンダリングを防ぐことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useContext, useState, useMemo, useCallback } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 function OptimizedProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [user, setUser] = useState&amp;lt;User | null&amp;gt;(null);&lt;br /&gt;
 &lt;br /&gt;
    // useCallback で関数参照を安定化する&lt;br /&gt;
    const login = useCallback(async (email: string, password: string) =&amp;gt; {&lt;br /&gt;
       const userData = await fetchUser(email, password);&lt;br /&gt;
       setUser(userData);&lt;br /&gt;
    }, []);&lt;br /&gt;
 &lt;br /&gt;
    const logout = useCallback(() =&amp;gt; {&lt;br /&gt;
       setUser(null);&lt;br /&gt;
    }, []);&lt;br /&gt;
 &lt;br /&gt;
    // useMemo でContext値をメモ化する&lt;br /&gt;
    const value = useMemo(&lt;br /&gt;
       () =&amp;gt; ({ user, login, logout }),&lt;br /&gt;
       [user, login, logout]&lt;br /&gt;
    );&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;UserContext.Provider value={value}&amp;gt;&lt;br /&gt;
          {children}&lt;br /&gt;
       &amp;lt;/UserContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Context分割パターン ====&lt;br /&gt;
1つの大きなContextに多くの値を格納すると、一部の値が変わるだけでそのContextを使用する全てのコンポーネントが再レンダリングされる。&amp;lt;br&amp;gt;&lt;br /&gt;
更新頻度の異なるデータを別々のContextに分割することにより、再レンダリングの範囲を最小化できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // 分割前 : 1つの大きなContext&lt;br /&gt;
 // theme が変わるだけで user を使うコンポーネントも再レンダリングされる&lt;br /&gt;
 const AppContext = createContext&amp;lt;{ theme: Theme; user: User | null } | undefined&amp;gt;(undefined);&lt;br /&gt;
 &lt;br /&gt;
 // 分割後 : 役割ごとに独立したContext&lt;br /&gt;
 const ThemeContext = createContext&amp;lt;Theme | undefined&amp;gt;(undefined);&lt;br /&gt;
 const UserContext = createContext&amp;lt;User | null | undefined&amp;gt;(undefined);&lt;br /&gt;
 &lt;br /&gt;
 // StateとDispatchを分離するパターン (useReducerとの組み合わせで特に有効)&lt;br /&gt;
 const StateContext = createContext&amp;lt;AppState | undefined&amp;gt;(undefined);&lt;br /&gt;
 const DispatchContext = createContext&amp;lt;React.Dispatch&amp;lt;AppAction&amp;gt; | undefined&amp;gt;(undefined);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== useContextとuseReducerの組み合わせ ==&lt;br /&gt;
&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;useReducer&amp;lt;/code&amp;gt; を組み合わせることにより、ReduxのようなグローバルなFlux状態管理パターンを実現できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
StateContextとDispatchContextを分離することで、状態を読み取るだけのコンポーネントはアクションを発行しても再レンダリングされず、パフォーマンスが向上する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { createContext, useContext, useReducer, useMemo } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 interface AppState {&lt;br /&gt;
    count: number;&lt;br /&gt;
    user: User | null;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 type AppAction =&lt;br /&gt;
    | { type: &amp;#039;INCREMENT&amp;#039; }&lt;br /&gt;
    | { type: &amp;#039;DECREMENT&amp;#039; }&lt;br /&gt;
    | { type: &amp;#039;SET_USER&amp;#039;; payload: User | null };&lt;br /&gt;
 &lt;br /&gt;
 function appReducer(state: AppState, action: AppAction): AppState {&lt;br /&gt;
    switch (action.type) {&lt;br /&gt;
       case &amp;#039;INCREMENT&amp;#039;:&lt;br /&gt;
          return { ...state, count: state.count + 1 };&lt;br /&gt;
       case &amp;#039;DECREMENT&amp;#039;:&lt;br /&gt;
          return { ...state, count: state.count - 1 };&lt;br /&gt;
       case &amp;#039;SET_USER&amp;#039;:&lt;br /&gt;
          return { ...state, user: action.payload };&lt;br /&gt;
       default:&lt;br /&gt;
          return state;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // StateとDispatchを別々のContextに分離する&lt;br /&gt;
 const StateContext = createContext&amp;lt;AppState | undefined&amp;gt;(undefined);&lt;br /&gt;
 const DispatchContext = createContext&amp;lt;React.Dispatch&amp;lt;AppAction&amp;gt; | undefined&amp;gt;(undefined);&lt;br /&gt;
 &lt;br /&gt;
 const initialState: AppState = { count: 0, user: null };&lt;br /&gt;
 &lt;br /&gt;
 export function AppStateProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const [state, dispatch] = useReducer(appReducer, initialState);&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;DispatchContext.Provider value={dispatch}&amp;gt;&lt;br /&gt;
          &amp;lt;StateContext.Provider value={state}&amp;gt;&lt;br /&gt;
             {children}&lt;br /&gt;
          &amp;lt;/StateContext.Provider&amp;gt;&lt;br /&gt;
       &amp;lt;/DispatchContext.Provider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 状態を読み取るカスタムHook&lt;br /&gt;
 export function useAppState(): AppState {&lt;br /&gt;
    const context = useContext(StateContext);&lt;br /&gt;
    if (!context) throw new Error(&amp;#039;useAppState は AppStateProvider の内側で使用してください&amp;#039;);&lt;br /&gt;
    return context;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // アクションを発行するカスタムHook&lt;br /&gt;
 export function useAppDispatch(): React.Dispatch&amp;lt;AppAction&amp;gt; {&lt;br /&gt;
    const context = useContext(DispatchContext);&lt;br /&gt;
    if (!context) throw new Error(&amp;#039;useAppDispatch は AppStateProvider の内側で使用してください&amp;#039;);&lt;br /&gt;
    return context;&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== よくある間違い ==&lt;br /&gt;
&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; を使用する時によく発生する誤りと対処法を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Provider未配置 ====&lt;br /&gt;
&amp;lt;code&amp;gt;useContext&amp;lt;/code&amp;gt; を呼び出したコンポーネントが、対応するProviderの外側に配置されている場合、&amp;lt;code&amp;gt;createContext&amp;lt;/code&amp;gt; に渡したデフォルト値が返される。&amp;lt;br&amp;gt;&lt;br /&gt;
デフォルト値が &amp;lt;u&amp;gt;undefined&amp;lt;/u&amp;gt; の場合、プロパティアクセスでエラーが発生する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // 誤り : ThemeProviderの外側でuseThemeを呼び出している&lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;div&amp;gt;&lt;br /&gt;
          // ThemeToggleButtonは、ThemeProviderの外側にある&lt;br /&gt;
          &amp;lt;ThemeToggleButton /&amp;gt;&lt;br /&gt;
          &amp;lt;ThemeProvider&amp;gt;&lt;br /&gt;
             &amp;lt;Main /&amp;gt;&lt;br /&gt;
          &amp;lt;/ThemeProvider&amp;gt;&lt;br /&gt;
       &amp;lt;/div&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 正しい : ThemeProviderの内側に配置する&lt;br /&gt;
 function App() {&lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeProvider&amp;gt;&lt;br /&gt;
          &amp;lt;ThemeToggleButton /&amp;gt;&lt;br /&gt;
          &amp;lt;Main /&amp;gt;&lt;br /&gt;
       &amp;lt;/ThemeProvider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
また、コンポーネント関数の内側でProviderを返しても、そのコンポーネント自体はProviderの外側にあるため、自分自身はContextの値を受け取ることができない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // 誤り : useTheme() は ThemeProvider より上の階層で呼び出されている&lt;br /&gt;
 function ThemeAwareProvider({ children }: { children: React.ReactNode }) {&lt;br /&gt;
    const { theme } = useTheme(); // この時点ではまだProviderが存在しない&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ThemeProvider&amp;gt;&lt;br /&gt;
          &amp;lt;div className={theme}&amp;gt;&lt;br /&gt;
             {children}&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;/ThemeProvider&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 不必要なContext使用 ====&lt;br /&gt;
Contextは、アプリケーション全体 または 複数の深い階層に渡って、データを共有する場合に適したツールである。&amp;lt;br&amp;gt;&lt;br /&gt;
1〜2階層のデータ受け渡しであれば、Propsを使用する方がシンプルでデータの流れが明確になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // 不必要なContextの例 : 1階層だけならPropsで十分&lt;br /&gt;
 // Context使用 (過剰)&lt;br /&gt;
 function Parent() {&lt;br /&gt;
    return &amp;lt;UserNameContext.Provider value=&amp;quot;田中&amp;quot;&amp;gt;&amp;lt;Child /&amp;gt;&amp;lt;/UserNameContext.Provider&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function Child() {&lt;br /&gt;
    const name = useContext(UserNameContext);&lt;br /&gt;
    return &amp;lt;p&amp;gt;{name}&amp;lt;/p&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // Propsを使用 (適切)&lt;br /&gt;
 function Parent() {&lt;br /&gt;
    return &amp;lt;Child name=&amp;quot;田中&amp;quot; /&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function Child({ name }: { name: string }) {&lt;br /&gt;
    return &amp;lt;p&amp;gt;{name}&amp;lt;/p&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
下表に、PropsとContextの使い分けの目安を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Props と Contextの使い分け&lt;br /&gt;
! 状況 !! 推奨手段&lt;br /&gt;
|-&lt;br /&gt;
| 1〜2階層のデータ受け渡し || Props&lt;br /&gt;
|-&lt;br /&gt;
| 多くのコンポーネントで必要なデータ || Context&lt;br /&gt;
|-&lt;br /&gt;
| コンポーネントツリーの深い階層へのデータ伝達 || Context&lt;br /&gt;
|-&lt;br /&gt;
| テーマ、認証、言語設定などのグローバルな状態 || Context&lt;br /&gt;
|-&lt;br /&gt;
| 局所的なコンポーネント状態 || useState / useReducer (Propsで渡す)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 関連情報 ==&lt;br /&gt;
* [[Reactの基礎 - Hooksの基礎]]&lt;br /&gt;
* [[Reactの基礎 - useReducer]]&lt;br /&gt;
* [[Reactの基礎 - カスタムHook]]&lt;br /&gt;
* [[Reactの基礎 - PropsとChildren]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板,React,JavaScript,TypeScript,TSX,useContext,Context API,createContext,Provider,Prop Drilling,useState,useReducer,useMemo,useCallback,カスタムHook,テーマ,認証,i18n,国際化,React 19&lt;br /&gt;
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:Rust]][[カテゴリ:Web]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>