React RecoilでグローバルなStateを作成する
React+TypeScriptの環境で、Recoilを使用して、グローバルな状態State(グローバル変数)を作成します。
React createContextでグローバルなStateを作成するでcreateContextを使用したグローバル変数を作成しましたが、Recoilを使えばもっとシンプルにグローバル変数作成できます。
パッケージのインストール
まずはRecoilのパッケージをインストールします。
$ npm install recoilルートコンポーネントの修正
以下のように、ルートコンポーネントにRecoilRootを追加します。
RecoilRootの子コンポーネントの全てで、Recoilのグローバル変数が使用できるようになります。
import { RecoilRoot } from 'recoil';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
<RecoilRoot>
<App />
</RecoilRoot>
</React.StrictMode>
);atomの作成
Recoilではグローバル変数はatomを使用して作成します。
import { atom } from 'recoil';
const loadingState = atom<boolean>({
key: 'loadingState', // プロジェクト全体でユニークとなる値
default: false,
});atom<型>の形式でグローバル変数を定義します。
keyにはプロジェクト全体でユニークとなる値を設定します。
規模が大きいプロジェクトの場合はkeyの値は別ファイルで管理したほうが良いかと思います。
defaultには初期値を設定します。
カスタムフックの作成
作成したatomはuseRecoilState(atom変数)で参照します。
各コンポーネントでuseRecoilStateで参照する形でも問題ありませんが、ここではカスタムフックを作成します。
グローバル変数のゲッター、セッターだけではなく、グローバル変数を使用した共通処理もグローバルファンクションとして一緒に定義することが多いと思うので、カスタムフックとして定義しておき、各コンポーネントでカスタムフックを経由して使用します。
useApp.tsximport { useCallback } from 'react';
import { atom, useRecoilState } from 'recoil';
const loadingState = atom<boolean>({
key: 'loadingState', // プロジェクト全体でユニークとなる値
default: false,
});
export const useLoading = () => {
const [loading, setLoading] = useRecoilState(loadingState);
return {
loading,
setLoading,
toggleLoading: useCallback(() => {
setLoading((current) => !current);
}, [setLoading]), // 必要に応じて独自のファンクションも追加
};
};useRecoilStateはuseStateと同じように[ゲッター, セッター]の形で使用できます。
使い方
以下のように使用します。
カスタムフックを経由して参照すれば、React createContextでグローバルなStateを作成するで紹介したcontextを使用する場合と同じ方法で参照することができます。
MyComponent.tsximport useApp from './useApp';
const MyComponent = () => {
// recoilの値を参照可能
const { loading, setLoading } = useApp();
};