Masayan tech blog.

  1. ブログ記事一覧>
  2. Next.jsにRecoilを導入して、グローバルな状態管理を実装する

Next.jsにRecoilを導入して、グローバルな状態管理を実装する

公開日

環境

  • windows10
  • DockerDesktop for Win 3.5.x
  • Laravel 8.x
  • PHP 8.x
  • node 16.13.1
  • npm 8.1.2
  • TypeScript 4.5
  • React 17.0.1
  • Recoil 0.5.2
  • VsCode
  • gitbash 2.32.0.1

Recoilとは

概要

  • Facebook製のReact用状態管理ライブラリ
  • Context APIのデメリットとReduxの使いづらさを解消するために開発された

状態管理の位置づけ

導入コスト順(ほかにもあるかもしれませんが...)

  1. React標準のContext API(createContext, useContext)
  2. Recoil
  3. Redux

イメージ

Recoilでatomと呼ばれるstateを用意し、それをReactのすべてのコンポーネントから参照できるようにする

設定手順

Recoilの導入

インストール

npm install recoil

Recoilの基本的な使い方

ルートコンポーネントをRecoilRootコンポーネントでラップする

Next.jsなら_app.tsx

frontend\next-web\src\pages\_app.tsx

import { RecoilRoot } from 'recoil'

..割愛

  return (
    <RecoilRoot>
      <AuthProvider>
        <Component {...pageProps} />
      </AuthProvider>
    </RecoilRoot>
  )
}

export default MyApp

グローバルstateを作成する

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

frontend\next-web\src\components\store\Auth\auth.js

import { atom } from 'recoil'

export const userState = atom({
  key: 'user',
  default: {
    id: null,
    name: '',
    email: ''
  }
})

グローバルstateを使用する

作成したatomを使用したいコンポーネント上でimportして、ローカルstateとして宣言するだけ。

※recoileのhooksは、RecoilRootでラップされているコンポーネントからしか使用できないので注意(今回の例だと、app.tsxから呼び出そうとするとエラーになる)

frontend\next-web\src\pages\index.tsx

import { useRecoilState, useRecoilValue } from 'recoil'
import { userState } from 'components/store/Auth/auth'

...割愛

const Home = () => {
  const [user, setUser] = useRecoilState(userState)

  // useRecoilValueで値だけ宣言することも可能
  const user = useRecoilValue(userState)

  // apiなどからユーザー情報を取得して、setUserでグローバルstateを更新する
  console.log(user)

...割愛

トップページに遷移し、ログ出力されていればOK

Recoilでの値の永続化

  • 上記でだけでは、リロードするとstateがリセットされるので、何かしらの方法で永続化させる必要がある
  • recoil-persistという永続化用の便利なライブラリがあるのでこちらを利用する

インストール

npm install recoil-persist

atomsを修正する

frontend\next-web\src\components\store\Auth\auth.js

import { atom } from 'recoil'
import { recoilPersist } from 'recoil-persist' // 追加

const { persistAtom } = recoilPersist() // 追加

export const userState = atom({
  key: 'user',
  default: {
    id: 1,
    name: 'masayan',
    email: 'masayan@gmail.com'
  },
  effects_UNSTABLE: [persistAtom] //追加
})

これだけで、永続化可能なグローバルstateを作成することが可能です。めっちゃ簡単!!

Hooksの宣言方法

// 読み取りのみ
const user = useRecoilValue<string>(userState);
// 書き込みのみ
const setUser = useSetRecoilState<string>(userState);
// 読み込み書き込み両方
const [user, setUser] = useRecoilState<string>(userState);

まとめ

いかがでしたでしょうか。本記事では、Next.jsにRecoilを導入して、グローバルな状態管理を実装しつつ状態を永続化する方法については紹介しています。Reduxよりも導入が簡単で使用方法もわかりやすいので、ReactやNext.jsで状態管理が必要なケースがあれば、ぜひ参考にしてみてください。