React: createContext と useState によるステート管理(サンプルあり)

📋 目次(クリックで展開)

React コンテキストを利用して、アプリケーション全体でステートを管理する方法を紹介します。コンテキストの作成は createContext メソッドで行い、コンテキストの取得は useContext メソッドで行います。

今回は、子コンポーネントのボタンクリックでコンテキストを更新し、親コンポーネントでコンテキストの値をバインドしています。

動作イメージ

createContext(AppState.ts)

createContext フックを使って、コンテキストオブジェクト menuContext を作成します。このコンテキストオブジェクトには、boolean 型の isOpen プロパティと、isOpen プロパティを切り替える setOpen メソッドが含まれます。

AppState.ts
import { createContext } from "react";
export const menuContext = createContext({
isOpened: false,
setOpened: (isOpen: boolean) => {}
});

useContext(Menu.tsx)

useContext フックを呼び出し、menuContext オブジェクトを引き込みます。ボタンクリック時に呼び出す、toggleOpen メソッドの中で isOpen プロパティの値を切り替えています。

Menu.tsx
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 で参照します。

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 による値の受け渡しよりも、ステート管理がすっきりと実装できます。

サンプルアプリケーション

react-usecontext-usestate-demo.zip

参考情報


💬 コメント