NextでRecoilおよびPersist使ってみる。
Create-React-App編はこちらをどうぞ。
やりたいこと・作るもの
ページを移動しても値が維持(共有)され、ページをリロードしても値が(保持したければ)保持されるという機能の検証。
準備
プロジェクトの作成
create-next-appを利用してプロジェクトを作成。
npx create-next-app next-recoil-test
cd next-recoil-test
recoilをインストール。
npm install recoil
ページが移動しても値が維持されることを確認したいのでpages以下にabout.jsを作成しておきます。
touch pages/about.js
recoilはatomを作成し、値を共有するのでatom定義用のファイルを用意しておきます。
comopnents以下にatoms.jsを作りました。
mkdir components
touch components/atoms.js
実装
では実装していきます。
_app.js
recoilでは値を共有したい範囲をRecoilRootで囲います。
通常はアプリ全体で共有するので_app.jsで定義します。
import '../styles/globals.css'
import { RecoilRoot } from "recoil"; //追加
const MyApp = ({ Component, pageProps }) => {
return (
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
);
}
export default MyApp;
atoms.js
atoms.jsの記述。ここではcountとuserという値を共有する値としたいと思います。
import { atom } from "recoil";
//count
export const countState = atom({
key: "count",
default: 0
});
//user
export const userState = atom({
key: "user",
default: {
name: "hoge",
age: 11
}
});
index.js
index.js(Home)にcountとuser情報を表示および編集する機能を実装してみます。
import Link from "next/link";
import { useRecoilState } from "recoil";
import { countState, userState } from "../components/atoms";
const Home = () => {
//atomの値の操作を定義(read,write)
const [count, setCount] = useRecoilState(countState);
const [user, setUser] = useRecoilState(userState);
//count increment処理
const increment = c => {
return c + 1;
}
//userのageをカウントアップ(機能としては意味無し)
const updateUser = u => {
return { ...u, ...{ age: u.age + 1 } };
}
return (
<>
<h1>Home</h1>
<div>
<p>count:{count}</p>
<button onClick={() => setCount(increment)}>count increment</button>
<hr />
<p>user.name:{user.name}</p>
<p>user.age:{user.age}</p>
<button onClick={() => setUser(updateUser)}>age increment</button>
</div>
<hr />
<div>
<Link href="/about"><a>About</a></Link>
</div>
</>
);
}
export default Home;
about.js
about.jsでは読み取りだけしてみたいと思います。
import Link from "next/link";
import { useRecoilValue } from "recoil";
import { countState, userState } from "../components/atoms";
const About = () => {
//atomの値の操作を定義(read only)
const count = useRecoilValue(countState);
const user = useRecoilValue(userState);
return (
<>
<h1>About</h1>
<div>
<p>count:{count}</p>
<p>user.name:{user.name}</p>
<p>user.age:{user.age}</p>
</div>
<hr/>
<div>
<Link href="/"><a>Home</a></Link>
</div>
</>
);
}
export default About;
動作確認
完成したら動作を確認してみます。
npm run dev
値の永続化(persist)
実アプリでデータの永続化は必須となります。
ここではuser情報だけを継続化したいと思います。redux-persistに比べかなり簡単です!
atoms.jsを少しいじるだけ。
モジュールのインストール
npm install recoil-persist
atoms.jsを改修
数行追加するだけ。便利。簡単。
import { atom } from "recoil";
import { recoilPersist } from "recoil-persist";
const { persistAtom } = recoilPersist();
//count
export const countState = atom({
key: "count",
default: 0
});
//user
export const userState = atom({
key: "user",
default: {
name: "hoge",
age: 11
},
effects_UNSTABLE: [persistAtom] //追加
});