環境
- 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の使いづらさを解消するために開発された
状態管理の位置づけ
導入コスト順(ほかにもあるかもしれませんが...)
- React標準のContext API(createContext, useContext)
- Recoil
- 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で状態管理が必要なケースがあれば、ぜひ参考にしてみてください。