これまで、React HooksのuseState,useEffect,useRefについて学んできました。
ここからは発展編ということで、必須ではありませんが、知っておくと便利なHooks(useContext,useReducer)について触れていきます。
💡useContextとは?
useContextは、「親コンポーネントから子コンポーネントにデータを渡すのをラクにする仕組み」 です。
普通、データを渡すには props
を使いますが、階層が深くなるとめちゃくちゃ面倒になります。
💩 「props 地獄」を解決するのが useContext
useContextの使い方

実際にコードを書いて動きを見ていきましょう。
まずアプリを作成します。
npx create-next-app@latest use-context-app
次に、useContextを定義するファイルを作成します。
app/UserContext.js
import { createContext } from "react";
// ✅ ユーザー情報を管理する Context を作成
export const UserContext = createContext();
そして、孫、子、親コンポーネントを作成していきます。
app/components/GrandChild.js
"use client";
import { useContext } from "react";
import { UserContext } from "../UserContext";
function GrandChild() {
const { user } = useContext(UserContext); // ✅ Context からユーザー情報を取得
return (
<div style={{ border: "2px solid blue", padding: "10px", marginTop: "10px" }}>
<h3>👶 孫コンポーネント</h3>
<p><strong>ユーザー名:</strong> {user.name}</p>
<p><strong>メールアドレス:</strong> {user.email}</p>
</div>
);
}
export default GrandChild;
app/components/Child.js
"use client";
import { useContext } from "react";
import { UserContext } from "../UserContext"; // ✅ Context をインポート
import GrandChild from "./GrandChild"; // ✅ 孫コンポーネントをインポート
function Child() {
const { user } = useContext(UserContext); // ✅ Context からユーザー情報を取得
return (
<div style={{ border: "2px solid green", padding: "10px" }}>
<h2>👦 子コンポーネント</h2>
<p><strong>ユーザー名:</strong> {user.name}</p>
<p><strong>メールアドレス:</strong> {user.email}</p>
<GrandChild /> {/* ✅ 孫コンポーネントを表示 */}
</div>
);
}
export default Child;
app/components/App.js
"use client";
import { useState } from "react";
import { UserContext } from "../UserContext"; // ✅ Context をインポート
import Child from "./Child"; // ✅ 子コンポーネントをインポート
function App() {
const [user, setUser] = useState({
name: "しょんべん太郎",
email: "shonben@example.com",
});
return (
// ✅ `UserContext.Provider` で `user` を全コンポーネントに提供
<UserContext.Provider value={{ user, setUser }}>
<div style={{ border: "2px solid red", padding: "10px" }}>
<h1>👨💻 親コンポーネント(App)</h1>
<p><strong>ユーザー名:</strong> {user.name}</p>
<p><strong>メールアドレス:</strong> {user.email}</p>
<Child />
</div>
</UserContext.Provider>
);
}
export default App;
最後にpage.jsで読み込みます。
app/page.js
import Image from "next/image";
import App from "./components/App";
export default function Home() {
return (
<App />
);
}





開発サーバーを立ち上げて画面を確認します。
npm run dev

このように親コンポーネントで定義した値をそれぞれのコンポーネントで継承し表示しています。
コード解説
まずUserContext.jsですが、
app/UserContext.js
export const UserContext = createContext();
このようにUserContextというContextを作成しています。
またexportの後に「default」をつけていませんが、コンポーネントなどの関数の宣言(function
)」は export default
でエクスポートできますが、今回のように定数の宣言の場合は「default」がつけられません。
次に、親コンポーネントの主要な部分を説明します。
app/components/App.js
import { UserContext } from "../UserContext"; // ✅ Context をインポート
UserContext.jsからUserConxetをインポートしています。
このように、「default」をつけずにエクスポートされたものは{}をつけて且つエクスポート元で定義した名前をそのまま記述する必要があります。
逆に、「default」をつけたエクスポートした関数はインポート先では別の名前でインポートすることもできます。
<UserContext.Provider value={{ user, setUser }}>
親コンポーネントではこのように渡したい値を「Provider」と呼ばれるコンポーネントのvalueプロパティに設定します。
valueの値が{{}}と二重括弧になっていますが、内側の{}はuser、setUserと複数の値を渡すためにオブジェクトとして渡すための{}です。
渡す値が1つの場合は{}は1重で大丈夫です。
次に子コンポーネントを見ます。
app/components/Child.js
import { UserContext } from "../UserContext";
子コンポーネントでもUserContext.jsからUserContextをインポートします。
const { user } = useContext(UserContext);
ここで親コンポーネントで設定された値をuseContextを使って受取り、{user}オブジェクトに代入しています。
ここでも、渡ってくる値が1つの場合は、{}をつけてオブジェクトにする必要はありません。
<p><strong>ユーザー名:</strong> {user.name}</p>
<p><strong>メールアドレス:</strong> {user.email}</p>
ここで親コンポーネントで定義したuserオブジェクトの値をそれぞれ表示しています。
userオブジェクト(app/components/App.js)
{
name: "しょんべん太郎",
email: "shonben@example.com",
}
最後に孫コンポーネントを見ていきます。
app/components/GrandChild.js
import { UserContext } from "../UserContext";
const { user } = useContext(UserContext);
<p><strong>ユーザー名:</strong> {user.name}</p>
<p><strong>メールアドレス:</strong> {user.email}</p>
このように、孫コンポーネントと子コンポーネントが全く同じ書き方になっています。
useContextでどこからでもデータにアクセスできる

propsでのデータ継承のように、親→子→孫とバケツリレーをしなくても、例えば子コンポーネントでは継承せずに、孫コンポーネントのみでも扱えたりします。
つまり、useContextを使うことで、
親コンポーネントで渡したデータにどこからでもアクセスできる
というわけです。
なので、子コンポーネントと孫コンポーネントで同じ書き方でも継承できたのです。
useContextを使うケース
ここで見てきたユーザー情報=ログイン情報ようなグローバルで扱いたいデータ向けに使用します。
コメント