React16.8から加わったHooksの1つである、useContext
の使い方を自分用のメモとして記事を書きました。
CodeSandboxでサンプルコードをかきました。下記URLからコードを確認していただくと、分かりやすいと思います。
https://codesandbox.io/embed/wispy-voice-1uwjo7?fontsize=14&hidenavigation=1&theme=dark
ソースコード
App.tsx
import "./styles.css";
import { Page1 } from "./Page1";
import { useState } from "react";
import React from "react";
type messageType = {
message: string;
setMessage: React.Dispatch<React.SetStateAction<string>>;
};
export const MessageContext = React.createContext({} as messageType);
export default function App() {
const [message, setMessage] = useState("Appページのメッセージ");
return (
<MessageContext.Provider value={{ message, setMessage }}>
<div className="App">
<h1>App</h1>
<p>{message}</p>
<Page1 />
</div>
</MessageContext.Provider>
);
}
Page1.tsx
import { Page2 } from "./Page2";
export const Page1 = () => {
return (
<div className="Page1">
<h1>Page1</h1>
<Page2 />
</div>
);
};
Page2.tsx
import React, { useContext } from "react";
import { MessageContext } from "./App";
export const Page2 = () => {
const { message, setMessage } = useContext(MessageContext);
const changeHandle = (event: React.ChangeEvent<HTMLInputElement>) => {
setMessage(event.target.value);
};
return (
<div className="Page2">
<h1>Page2</h1>
<input
value={message}
id="message"
onChange={(e) => {
changeHandle(e);
}}
/>
</div>
);
};
解説
App.tsxが上位に位置するコンポーネントであり、その中にPage1.tsxを配置し、さらにPage1.tsxの中にPage2.tsxが配置されています。
サンプルコードを操作していただくとわかりますが、Page2.tsxコンポーネントにあるinput要素へ文字を入力すると、App.tsxのテキストが同時に変化します。
App.tsx
App.tsxではexport const MessageContext = React.createContext({} as messageType);
でコンテクストオブジェクトを作成&エクスポートしています。
また<MessageContext.Provider value={{ message, setMessage }}>
で下位のコンポーネントを囲っています。これにより下位のコンポーネントがvalueで渡した値を使用することができ、その操作によって値が変化します。
サンプルコードではuseStateで作成した値をオブジェクトとして、valueで渡しています。
Page2.tsx
Page2.tsxでは、import { MessageContext } from "./App";
とexport const Page2 = () => { const { message, setMessage } = useContext(MessageContext);
によってApp.tsxで定義したvalueの値を受け取っています。
上記のようにすることで複数コンポーネントをまたいだ値の受け渡しを行うことができます。