Skip to main content

Recoil

最近更新が行われておらず、React 19に対応していないため死亡

悲しいね

Recoilとは

Recoilは、Facebookが開発したReact向けの状態管理ライブラリ。ReduxやMobXなどの他の状態管理ライブラリと比較して、より簡単に実装でき、Reactの機能との親和性が高いのが特徴。

主な特徴

  • シンプルなAPI
  • Reactのhooks APIとの高い互換性
  • 非同期データの扱いやすさ
  • 部分的な状態更新による効率的なレンダリング
  • TypeScriptのサポート

ユースケース

  • グローバルな状態管理が必要な場合
  • コンポーネント間で状態を共有する必要がある場合
  • 複雑な状態管理が必要な場合
  • パフォーマンスの最適化が必要な場合

Recoilの主要概念

1. Atom

  • 状態の最小単位
  • グローバルに共有される値を保持
  • 更新可能で、subscribable(監視可能)

2. Selector

  • atomまたは他のselectorから派生した状態
  • 状態の加工や計算に使用
  • 純粋関数として実装

Recoilのインストール

npm install recoil

Recoil の設定

Recoilを使うためには一番トップのコンポーネントにRecoilRootというコンポーネントでラップする必要がある。

layout.tsx'use client'をつけて、クライアントコンポーネントにするとApp Routerのメリットが得られなくなるため、Compositionを利用する。

src/app/recoilProvider.tsx
'use client'
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil';

function RecoilProvider({ children }: { children: ReactNode }) {
return (
<RecoilRoot>{children}</RecoilRoot>
);
}

export default RecoilProvider;

src/app/layout.tsx
'use client';
//import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import RecoilProvider from './recoilProvider'; //別ファイルで作成したRecoilProviderをインポート
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

// export const metadata: Metadata = {
// title: 'Create Next App',
// description: 'Generated by create next app',
// };

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang='en'>
<body className={inter.className}>
<RecoilProvider>{children}</RecoilProvider>
</body>
</html>
);
}

atomの作成

Recoilの状態管理の核である、atom(グローバルstate)を作成

  • Recoilでは、stateをatomという単位で構成する
  • 以下では例として、ユーザーの情報を管理するatomを作成
  • keyの値はユニーク
  • atomとして設定した値は全コンポーネント間で状態が共有される
  • atomの値が更新されると、その値を使用しているコンポーネント全てに再レンダリングが走る

以下例

src/atoms/userState.ts
import { atom } from 'recoil'

export type User = {
id: number;
name: string;
email: string;
};

export const userState = atom<User[]>({
key: 'userState',
default: {
id: null,
name: '',
email: ''
}
})

Recoilの主要フック

1. useRecoilState

atomの値の取得と更新の両方が可能です。

const [value, setValue] = useRecoilState(myAtom);

2. useRecoilValue

atomの値の取得のみ可能です。

const value = useRecoilValue(myAtom);

3. useSetRecoilState

atomの値の更新のみ可能です。

const setValue = useSetRecoilState(myAtom);

4. useResetRecoilState

atomの値をデフォルト値にリセットします。

const resetValue = useResetRecoilState(myAtom);

Selectorの使用例

import { selector } from 'recoil';

export const userNameSelector = selector({
key: 'userNameSelector',
get: ({get}) => {
const user = get(userState);
return user.name.toUpperCase();
},
});

ベストプラクティス

  • アトムの分割
    • 適切な粒度でatomを分割する
    • 関連する状態をまとめる
  • 型定義の活用
    • TypeScriptを使用して型安全性を確保
  • 命名規則
    • atomは〜State
    • selectorは〜Selector
  • パフォーマンス最適化
    • 必要な部分のみを更新
    • 適切なメモ化の使用

注意点

  • Server Side Rendering (SSR)
    • RecoilRootはクライアントサイドでのみ動作
    • Next.jsでは適切な設定が必要
  • 状態の永続化
    • デフォルトでは永続化されない
    • 必要に応じて別途実装が必要

参考