React コンテキストを利用して、アプリケーション全体でステートを管理する方法を紹介します。コンテキストの作成は createContext メソッドで行い、コンテキストの取得は useContext メソッドで行います。
今回は、子コンポーネントのボタンクリックでコンテキストを更新し、親コンポーネントでコンテキストの値をバインドしています。
動作イメージ
createContext(AppState.ts)
createContext フックを使って、コンテキストオブジェクト menuContext を作成します。このコンテキストオブジェクトには、boolean 型の isOpen プロパティと、isOpen プロパティを切り替える setOpen メソッドが含まれます。
import { createContext } from "react"; export const menuContext = createContext({ isOpened: false, setOpened: (isOpen: boolean) => {} });
useContext(Menu.tsx)
useContext フックを呼び出し、menuContext オブジェクトを引き込みます。ボタンクリック時に呼び出す、toggleOpen メソッドの中で isOpen プロパティの値を切り替えています。
import React, { useContext } from "react"; import { menuContext } from "../contexts/AppState"; export const Menu = () => { // AppState.ts の menuContext を引数に与える const { isOpened, setOpened } = useContext(menuContext); // menuContext の isOpened プロパティを切り替える const toggleOpen = () => setOpened(!isOpened); return ( <div style={{ border: "1px solid gray", margin: "1rem", padding: "1rem" }}> <div>Menu.tsx</div> {/* menuContext の setOpened メソッドを呼び出す */} <button onClick={toggleOpen}>メニューの開閉</button> </div> ); };
useState(App.tsx)
Menu.tsx で切り替えられる isOpened の値を、Menu.tsx の親である App.tsx で参照します。
function App() { // AppState.menuContext に対応するプロパティを useState で用意する const [isOpened, setOpened] = useState(false); return ( <div style={{ border: "1px solid gray", margin: "1rem", padding: "1rem" }}> <div>App.tsx</div> {/* Provider 経由でステートをバインドする */} <menuContext.Provider value={{ isOpened, setOpened }}> <div> {/* 子コンポーネント(Menu.tsx)で切り替えた isOpened ステートをバインドする */} メニュー {isOpened ? "表示" : "非表示"} </div> <Menu /> </menuContext.Provider> </div> ); }
今回は、React コンテキストに夜、アプリケーションステートの管理方法を紹介しました。props による値の受け渡しよりも、ステート管理がすっきりと実装できます。