React フック【useContext 】の使い方 基礎
本日はReactフックでよく用いられる、useContext
でのデータ共有になります。
useContextフックは、React16.8以降のバージョンで使用可能です。
useContextとは
本来Reactでの親コンポーネントから子のコンポーネントへデータを渡す際はProps
でおこなわれます
ですが、複数の複雑化したコンポーネントがあった場合、Propsを経由してバケツリレー状態のデータを渡していくのは最善の方法とは言えません。
ReactのContext APIを利用すれば、データを子コンポーネントに渡す際にPropsを利用する事なく、 下の階層にあるコンポーネントとシンプルにデータの受け渡しが容易になります。
Context APIはデータの数値、関数、オブジェクトこれらを渡す時に非常に便利です。
簡単な使用例で学びましょう。
useContextフック 使い方
create-react-app(CRA)での解説となります。
まずは最上位である親コンポーネントのApp.js
ファイルから、子のコンポーネントに渡されたデータを取得します。
当記事ではContextRoot.Provider
というタグでラップして処理が必要となります。
// App.js <ContextRoot.Provider value={data}> <Child /> </ContextRoot.Provider>
それをせずに使用する方法もあります。
// App.js import Child from "./components/Child"; import ContextRoot from "./ContextRoot"; const data = { number: 123, text: "テスト", funcAlert: () => { alert("Hello, Welcome"); } } const App = () => { return ( <ContextRoot.Provider value={data}> <Child /> </ContextRoot.Provider> ); } export default App;
オブジェクトのdata
にはそれぞれ値を持たせます。
const data = { number: 123, text: "テスト", funcAlert: () => { alert("Hello, Welcome"); } }
ContextRoot.Provider
のタグ内のvalue
はPropsの役割でありオブジェクトのdate
を渡します。
この値は、そのすべての子とその子孫が利用できるようになります。
つまり、サブツリー全体でuseContext
フックを使用して値を読み取ることができます。
App.jsファイルが存在する同じ階層に、ContextRoot.js
というファイルを作成します。
このファイルは、ルートのファイルとなりContext
の作成はcreateContext
で行います。
// ContextRoot.js import { createContext } from 'react'; const ContextRoot = createContext(); expot default ContextRoot;
createContext
はコンテキストインスタンスを作成する為のものとなります。
そのため、コンテキストを作成し初期化をします。
createContextの引数は元々初期値
はありません。
createContextの引数にデフォルトの値を渡した場合ではReactのドキュメントによると、デフォルト値を指定すると『コンポーネントをラップせずに個別にテストするのに役立つ可能性がある』と明記してあります。
ですので、デフォルト値が役立つ状況がありますが、ほとんどの場合はデフォルト値は不要または有用ではありません。
それでは、App.jsのdata
を渡して取得していきましょう。
新しくComponents
というフォルダを作成して下さい。
その中に、Child.js
とGrandChild.js
の2つの新しいファイルを作成して下さい。
これは、子のコンポーネントと孫のコンポーネントファイルとなります。
// Child.js import GrandChild from "./GrandChild"; const Child = () => { return <GrandChild />; }; export default Child;
// GrandChild.js import { useContext } from "react"; import ContextRoot from "../ContextRoot"; const GrandChild = () => { const data = useContext(ContextRoot); return ( <div> <p>{data.number}</p> <p>{data.text}</p> <button onClick={data.funcAlert}>ボタン</button> </div> ); }; export default GrandChild;
子コンポーネントでコンテキストを使用するには、useContextフックを使用してコンテキストにアクセスする必要があります。
const data = useContext(ContextRoot);
ContextRootは、コンテキストオブジェクト(React.createContextから返される値)となります。
このメソッドは、そのコンテキストの現在の値を返します。
つまり、引数としてuseContextフックに渡される必要があるものとなります。
この値は、ツリー内で呼び出し元のコンポーネントの上にある、最も近い<MyContext.Provider>
タグのvalue props
によって決定されます。
ContextRootのデータを取得し、それをdata
という変数に再割り当てします。
そして、それを使用していくだけです。
それでは取得したのを表示していきましょう。
npm start
DEMO
See the Pen React useContext by dev.K | Webアプリ開発者 (@enjinia_f) on CodePen.
子であるChild.jsにはPropsを使用せず、グローバルとして子孫コンポーネントにデータを渡している事が分かるかと思います。
これは、データを取得してるのは子孫コンポーネントであるGrandChild.js
ファイルとなります。
最後に
Reactのコンテキストは、コンポーネントツリーの深さに関係なく、子コンポーネントにグローバルデータを提供できるようにする概念となっています。
ですが、コンテキストをアプリケーションに統合するときは、かなり複雑になることを考慮してください。
しかし、アプリケーションがシンプルで小規模なアプリケーションの場合では、useContextフックはReduxの実行可能な代替手段になる可能性があります。
どのように書いていくかではなく、まずはデータの受け渡しの流れを理解する事が重要です。
本日は以上となります。
この記事が気に入ったら、ブックマークし他の方に共有して下さい👏
この記事で解説したuseContextフックの流れの理解に役立つことを私は願っています。