🐣 【日報】React実践の教科書 P183〜187
作成日: 2021/12/23
2

今日やったこと

  • 「モダンJavaScriptの基本から始める React実践の教科書」 P183〜187
    • 7-2 ContextでのState管理
      • ContextでのグローバルStateの基本的な使い方

学習メモ

ContextでのグローバルStateの使用方法には大きく分けて以下の3つのステップがある

  1. React.createContextでContextの器を作成する
  2. 作成したContextのProviderでグローバルStateを扱いたいコンポーネントを囲む
  3. Stateを参照したいコンポーネントでReact.useContextを使う

1. React.createContextでContextの器を作成する

./src/components/providers/AdminFlagProvider.jsx を作り、Contextの器を作成

import { createContext } from "react";

export const AdminFlagContext = createContext({});

2. 作成したContextのProviderでグローバルStateを扱いたいコンポーネントを囲む

AdminFlagProvider.jsx

import { createContext } from "react";

export const AdminFlagContext = createContext({});

export const AdminFlagProvider = props => {
    const { children } = props;

    // 動作確認のために適当なオブジェクトを定義
    const sampleObj = { sampleValue: "テスト" };

    // AdminFlagContextの中にProviderがあるのでそれでchildrenを囲む
    // valueの中にグローバルに扱う実際の値を設定
    return (
        <AdminFlagContext.Provider value={sampleObj}>
            {children}
        </AdminFlagContext.Provider>
    );
};
  • Providerコンポーネントは何でも囲めるようにPropsとしてchildrenを受け取るようにするのがポイント
  • AdminFlagContextの中にProviderが用意されているので、それを返却していく
  • ProviderコンポーネントはvalueというPropsを設定することができ、ここにグローバルに管理する実際の値を渡していく(今はサンプル用のオブジェクトを設定)

index.js内で参照したいコンポーネントを囲む

import ReactDOM from 'react-dom';
import { App } from './App';
import { AdminFlagProvider } from "./components/providers/AdminFlagProvider";

ReactDOM.render(
  <AdminFlagProvider>
    <App />
  </AdminFlagProvider>,
  document.getElementById('root')
);

これで全てのコンポーネントが作成したProviderで囲まれた状態になる

3. Stateを参照したいコンポーネントでReact.useContextを使う

試しにContextの値をEditButton.jsxから参照

// "react"からuseContextをimport
import { useContext } from "react";

// 作成したContextをimport
import { AdminFlagContext } from "./providers/AdminFlagProvider";

// …省略

export const EditButton = props => {
	// …省略

    // useContextの引数に参照するContextを指定する
    const contextValue = useContext(AdminFlagContext);
    console.log(contextValue); // {sampleValue: "テスト"}

	// …省略
};

useContextで取得した値にContextで設定したオブジェクトが入っていることが確認できた

所感

状態管理については、Reduxのようなライブラリの名前を耳にすることが多く
デフォルトで用意されているContextを使うケースは少ないのかもしれませんが、知ることができて良かったです。

また、React公式の「コンテクストを使用する前に」というテキストで、Contextを使わずにバケツリレーを避ける方法が書かれていました。

Propsではなく、コンポーネント自身を渡せば、間のコンポーネントでPropsを読み込む必要がなくなるというものです。

このような、できるだけグローバルなStateを作らないようにするための引き出しをたくさん持っておきたいです。