前回はuseReducerについて書きましたが、今回はuseContextについての備忘録です。
useContextとは
通常propsを渡す歳に、親から子、子から孫みたいなコンポーネントツリーをバケツリレーで渡すのですが、useContextを使用すれば親から直接孫へpropsを渡すことができます。
使い方
以下の様なディレクトリ構造があるとします。
.
├── App.jsx
└── components
├── Child.jsx
└── Grandchild.jsx
まず親要素にcreateContext
で関数を作成します。
App.jsx
import { createContext } from "react" // インポートでcreateContextを読み込む
import { Child } from "./component/Child";
export const helloContext = createContext("Hello World"); // helloContextを作成。初期値は「Hello World」
export default function App() {
return (
<div className="App">
<h1>useContextの練習</h1>
<Child /> {// ここで子コンポーネントが呼び出されている}
</div>
);
}
次に渡したいコンポーネントにuseContext
で渡します。
今回はGrandchild.jsxにuseContextを書いていきます。
Grandchild.jsx
import { useContext } from "react"; // useContextを読み込む
import { helloContext } from "../App"; // App.jsxで作成したhelloContextを読み込む
export const Grandchild = () => {
const value = useContext(helloContext); // useContextの引数としてhelloContextを渡してそれを代入
return (
<div style={{ backgroundColor: "skyblue", color: "white" }}>
<h3>孫コンポーネントです</h3>
<p>渡ってきた値は {value} です</p> {// 代入された値を表示する}
</div>
);
};
ChildコンポーネントにGrandchildコンポーネントを読み込ませます。
Child.jsx
import { Grandchild } from "./Grandchild";
export const Child = () => {
return (
<div style={{ padding: "10px", backgroundColor: "blue" }}>
<h2>子コンポーネントです</h2>
<Grandchild />
</div>
);
};
DEMO
App→Child→GrandchildではなくApp→Grandchildで値が渡っているのが分かるかと思います。
任意の値を渡したい場合
上記のコードでは初期値の「Hello World」が表示されていますが、違う値を渡したい場合はProvider
コンポーネントを使用します。
import "./styles.css"
import {createContext} from "react"
import {Child} from "./component/Child"
export const helloContext = createContext("Hello World")
export default function App() {
return (
<div className="App">
<h1>useContextの練習</h1>
+ <helloContext.Provider value={"こんにちは世界"}>
<Child />
+ </helloContext.Provider>
</div>
)
}
DEMO
Providerコンポーネントを親と子で両方で使用した場合
以下Childコンポーネント
import { Grandchild } from "./Grandchild";
+ import { helloContext } from "../App";
export const Child = () => {
return (
<div style={{ padding: "10px", backgroundColor: "blue" }}>
<h2>子コンポーネントです</h2>
+ <helloContext.Provider value={"Good Bye"}>
<Grandchild />
+ </helloContext.Provider>
</div>
);
};
DEMO
親と子の両方で値を定義したら、表示させる一番近いコンポーネントが優先されるようです。
この場合は子コンポーネントであるChild.jsx
に記述されたProviderが優先されました。
参考サイト