React hooksのuseContextについて勉強した。
バケツリレー(props drilling)問題とは
親=>子供=>孫=>ひ孫のように コンポーネント間でデータを渡すような事があった場合に propsで渡していかないといけない。 このような問題の事をバケツリレー(props drilling)という。
useContextとは
親で設定した内容を
親======>ひ孫
を渡せる機能
図にすると
↓
簡単に渡せるようになりバケツリレー問題が解決されます。
useContextの使い方
基本には親のコンポーネントで共有したい変数を設定します。
例
export const ThemeContext = React.createContext();
exportするのは子供以下のコンポーネントで使うための準備になります。
作ったContextを使用したい範囲を設定します。必ずvalueを設定しなければならないです
contextの設定前
<div className="App"> <h1>App(親)</h1> 親の変数のthemeは{theme}です <ChildrenApp /> </div>
contextの設定後
<ThemeContext.Provider value={{ theme, setTheme }}> <div className="App"> <h1>App(親)</h1> 親の変数のthemeは{theme}です <ChildrenApp /> </div> </ThemeContext.Provider>
valueはuseStateみたいなfunctionも持たせることができます。
親の方は完了です。
子供以下のコンポーネントで使うためには 親で宣言したcontextをimportします
import { ThemeContext } from "./App";
そして変数として呼びだします
const { theme, setTheme } = useContext(ThemeContext);
あとはどこでも使えます
useContextのサンプル
アタマが悪い私はいつもどおりサンプルを作って学習しました。
親、子、孫のコンポーネントの関係です.
親
import React, { useState } from "react"; import ChildrenApp from "./ChildrenApp"; export const ThemeContext = React.createContext(); export default function App() { console.log("app"); const [theme, setTheme] = useState("dark"); return ( <ThemeContext.Provider value={{ theme, setTheme }}> <div className="App"> <h1>App(親)</h1> 親の変数のthemeは{theme}です <ChildrenApp /> </div> </ThemeContext.Provider> ); }
子供
import React from "react"; import Grandchild from "./Grandchild"; const ChildrenApp = () => { console.log("children"); return ( <> <div> <h2>childrenApptest</h2> <Grandchild /> </div> </> ); }; export default ChildrenApp;
孫
import React, { useContext } from "react"; //AppコンポーネントからThemeContextをimport import { ThemeContext } from "./App"; export default function Grandchild() { const { theme, setTheme } = useContext(ThemeContext); console.log("Grandchild"); return ( <> <h3>Grandchildtest</h3> <div>現在のテーマは{theme}</div> <button onClick={() => setTheme("light")}>Lightに変更する</button> <button onClick={() => setTheme("dark")}>Darkに変更する</button> </> ); }
結果
孫のコンポーネントで変更した内容が親のコンポーネントまで反映されています
注意事項
useContextを使用すると、コンポーネントの独立性の多くが失われることに注意することが重要です。このため、useContextに依存するコンポーネントを再利用することはより困難です。
感想
状態管理がかなりめんどくさいかった。親子レベルなら単純にpropsで渡せばいいけど、親=>子供=>孫=>ひ孫までパラメータを渡すのはかなり辛かったのでこの機能は本当にありがたい。
参考URL
https://qiita.com/seira/items/fccdf4e73c59c491558d
https://blog.webdevsimplified.com/2020-06/use-context/
https://blog.logrocket.com/react-reference-guide-context-api/