recoil-persist で Recoil のステートを永続化する
Recoil は Meta が開発している React の状態管理ライブラリです
雑に言うと props を渡さなくてもグローバルな state を作ることができます
recoil-persist を使うと Recoil のステートを localStorage に永続化することができます
Recoil のサンプルでも localStorage に永続化する例がある
面倒な effect を自分で定義しなくて済む
インストール
code:console
$ yarn add recoil recoil-persist
Recoil のセットアップ
Recoil を使用したいコンポーネントを <RecoilRoot> で囲みます
Next.js を使っているなら、_app.tsx で以下のように <Component /> を <RecoilRoot> で囲んであげます
code:_app.tsx
import { RecoilRoot } from 'recoil'
const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
return (
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
)
}
export default MyApp
Atom の作成
Atom は Recoil の概念の一つで、状態を管理するもの
もう一方は Selector で、Atom を加工して値を返すもの
Atom は以下のように定義します
countState は localStorage に永続化されるようになります
上手く型推論ができていないようだったので明に <number> を付けています
code:atoms.ts
import { atom } from 'recoil'
import { recoilPersist } from 'recoil-persist'
const { persistAtom } = recoilPersist()
export const countState = atom<number>({
key: 'count',
default: 0,
// 永続化を有効にするなら以下を加える
})
永続化するストレージを選択するには recoilPersist() にオプションを渡します
ただし Next.js などで非ブラウザなコンテキストから使用すると ReferenceError: sessionStorage is not defined が発生してしまいます。。。
のように typeof window === 'undefined' の判定を加えることでブラウザ判定をすることが可能です
storage に関数を渡したいと思うところ
code:atoms.ts
const { persistAtom } = recoilPersist({
key: 'recoil-persist',
storage: sessionStorage,
})
Atom の値を読み書きする
Atom を React コンポーネントから読み書きするには useRecoilState() を使用します
引数には作成した Atom を渡します
useRecoilState は useState と同じような使い勝手です
1番目には Atom の値が、2番目には Atom の値を更新する関数が返ります
この例では上記で Atom の永続化をしているので、ページをリロードしてもカウンターがリセットされません
この例は別に Recoil の必要性はないです...
code:index.tsx
import { useRecoilState } from 'recoil'
export const Index: React.FC = () => {
useEffect(() => {
const interval = setInterval(() => {
setCount((previous) => previous + 1)
}, 1000)
return () => {
clearInterval(interval)
}
}, [])
return (
<>
<p>{count}</p>
</>
)
}
useRecoilValue も使ってみたい
使用したライブラリ バージョン