zukucode
主にWEB関連の情報を技術メモとして発信しています。

React createContextでグローバルなStateを作成する

React+TypeScriptの環境で、createContextを使用して、グローバルな状態State(グローバル変数)を作成します。

Providerの作成

まずは以下のようにグローバル変数の型を作成します。

今回はAppContextという名前で、ローディング状態とローディング状態を設定する関数を定義しています。

AppProvider.tsx
export const AppContext = createContext<
  | {
      logding: boolean;
      setLoading: (show: boolean) => void;
    }
  | undefined
>(undefined);
AppContext.displayName = 'AppContext';

次にコンポーネントを作成する要領で、グローバルな変数を定義します。

AppProvider.tsx
type Props = {
  children: ReactNode;
};

const AppProvider = ({ children }: Props) => {
  // ローディング状態を管理するステート
  const [loading, setLoadingInner] = useState<boolean>(false);

  // ローディング状態を変更するファンクション
  const setLoading = useCallback((show: boolean) => {
    setLoadingInner(show);
  }, []);

  const value = useMemo(() => {
    return {
      loading,
      setLoading,
    };
  }, [loading, setLoading]);

  return (
    <AppContext.Provider value={value}>
      {children}
    </AppContext.Provider>
  );
};

export default AppProvider;

このコンポーネントの子要素(children)の全てで、ここで定義した変数を使用できるようになります。

例えば以下のようにすれば、MyComponentのコンポーネントでloadingなどを参照できるようになります。

import AppProvider from './AppProvider';

const App = () => {
  return (
    <AppProvider>
      <MyComponent>
    </AppProvider>
  );
};

参照方法

各コンポーネントでuseContextを使用して参照することができますが、<AppProvider>の外で定義されたコンポーネントの場合、contextundefinedになります。

各コンポーネントでundefinedのタイプチェックをするのは面倒なので、contextを参照するためのフックを作成します。

useApp.ts
import { useContext } from 'react';
import { AppContext } from './AppProvider';

const useApp = () => {
  const context = useContext(AppContext); // contextはundefinedの可能性がある

  if (context === undefined) {
    throw new Error('useAppはAppProvider配下で使用してください。');
  }

  return context; // contextはundefinedではない
};

各コンポーネントでは、useContextではなくuseAppを使用して、参照します。

MyComponent.tsx
import useApp from './useApp';

const MyComponent = () => {
  // contextの値を参照可能
  const { loading, setLoading } = useApp();
};

グローバル変数を定義する別の方法として、Recoilを使用する方法があります。

Recoilを使用したグローバル変数の作成方法についてはReact RecoilでグローバルなStateを作成するで紹介しています。


関連記事