RecoilのAtomをlocalStorageに保存して読み込む
注意点
- より良いやり方があると思うので教えてください
- AtomEffectは使っていません(今後試す予定)
TL;DR
- setIntervalで1000ms毎に状態を取得して保存
- RecoilRootのinitializeState に渡して読み込む
環境
Next.js 12.0.7 + Recoil 0.5.2
本題
Atoms の用意
atoms/states.ts
import { atom } from "recoil"; export const activityListState = atom<{ id: string; date: number | Date }[]>({ key: "activityListState", default: [], }); export const taskListState = atom<string[]>({ key: "taskListState", default: [], });
- activityListState, taskListState の2つを用意
保存
pages/sandbox.tsx
import { useEffect } from "react"; import { useRecoilState } from "recoil"; import { activityListState, taskListState } from "../atoms/states"; function Sandbox() { const [taskList] = useRecoilState(taskListState); const [activityList] = useRecoilState(activityListState); useEffect(() => { const interval = setInterval(() => { if ( localStorage.getItem("activityListState") !== JSON.stringify(activityList) ) { localStorage.setItem("activityListState", JSON.stringify(activityList)); } if (localStorage.getItem("taskListState") !== JSON.stringify(taskList)) { localStorage.setItem("taskListState", JSON.stringify(taskList)); } }, 1000); return () => clearInterval(interval); }, [activityList, taskList]); return <div />; } export default Sandbox;
- useEffect内でsetIntervalを使用してstateの変更を取得しsetItemしている
読み込み
_app.tsx
import { useEffect, useState } from "react"; import type { AppProps } from "next/app"; import { RecoilRoot } from "recoil"; import { activityListState, taskListState } from "../atoms/states"; function MyApp({ Component, pageProps }: AppProps) { const [taskList, setTaskList] = useState([]); const [activityList, setActivityList] = useState([]); useEffect(() => { setTaskList(JSON.parse(localStorage.getItem("taskListState") || "[]")); setActivityList( JSON.parse(localStorage.getItem("activityListState") || "[]") ); }, []); return ( <RecoilRoot initializeState={(mutableSnapshot) => { mutableSnapshot.set(activityListState, activityList); mutableSnapshot.set(taskListState, taskList); }} > <Component {...pageProps} /> </RecoilRoot> ); } export default MyApp;
- initializeStateとmutableSnapshotというものを使ってlocalStorageの値をatomsの初期stateに入れる。