環境
- npm 8.6.0
- React 17.0.2
初めに
本記事では題名の通り、useContextにて宣言された変数の値を他のコンポーネントから再度定義する方法について紹介します。
その前に簡単ではありますが、useContextについて触れておきます。
そんなのわかっているよ!!!早く解決方法を!!!
という方は「解決方法」までスキップしてください。
useContextとは
簡単な使用例
app.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import ComponentA from "./components/ComponentA";
export const ThemeContext = React.createContext();
function App() {
const [theme, setTheme] = useState("indexから定義しています!");
return (
<ThemeContext.Provider value={{ theme }}>
<ComponentA />
</ThemeContext.Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ComponentA.js
import { useContext } from "react";
import { ThemeContext } from "../index";
const ComponentA = () => {
const { theme } = useContext(ThemeContext);
return <div>{theme}</div>;
};
export default ComponentA;
出力される画面の様子
こちらの使用方法ですが、親コンポーネントにて定義された値を取得して子コンポーネントにて表示していますが、子コンポーネントからその値を更新したいと状況ってあると思います。
そちらの方法を紹介していきます。
解決方法
親コンポーネントのStateにて定義されている値とそのセッター関数のどちらもProviderのValueに渡し、子コンポーネントにてセッター関数を呼び出すことでContextで定義された値を変更することが可能になります。
イメージとしてはstateに定義されている値に加えて、そのセッター関数もContext(→つまり、グローバル変数)として用意してあげることで、どのコンポーネントからでも使えるようにした、ということです。
app.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import ComponentA from "./components/ComponentA";
export const ThemeContext = React.createContext();
function App() {
const [theme, setTheme] = useState("indexから定義しています!");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<ComponentA />
</ThemeContext.Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ComponentA.js
import { useContext } from "react";
import { ThemeContext } from "../index";
const ComponentA = () => {
const { theme, setTheme } = useContext(ThemeContext);
const clickHandler = () => {
setTheme("子コンポーネントからContextに値をセットすることも可能です!");
};
return (
<div>
<p>{theme}</p>
<button onClick={clickHandler}>押すとコメントが変わります</button>
</div>
);
};
export default ComponentA;
出力される画面の様子
上記の画面にてボタンを押下すると次のように遷移します。
ボタン押下後の画面の様子
ボタン押下により、何が起きているかをステップに分けて説明していきます。
- ボタン押下によりbuttonタグのonClickメソッドが起動します。
- そのonClickにて宣言されているclickHandlerにて記載されているsetThemeメソッドが起動します。
- setThemeメソッドはuseStateにて定義されたThemeの値を変えるメソッドなので、Themeの値が更新されます。
- stateが更新されたことでコンポーネントが再レンダーされ、子コンポーネントの値が現在のThemeの値に書き換わるという訳です。
コード記述に関しての注意書き
私を2日間も苦しめた内容を共有します。
親コンポーネントにて定義されているStateの命名は子コンポーネントで必ず同じものでなければなりません。
つまり
親コンポーネントにて定義されている
const [theme, setTheme]
子コンポーネントにて定義されている
const { theme, setTheme }
これらの命名は同じでなければならないということです。
同じでないとundefiedが返ってきます。
useContextにてContextへ値をセットする - Codesandbox
useContextにてContextへ値をセットする using react, react-dom, react-scripts
終わり
コメント