LoginSignup
28
17

More than 1 year has passed since last update.

Recoil最低限 Next編 (2021年9月)

Posted at

NextでRecoilおよびPersist使ってみる。
Create-React-App編はこちらをどうぞ。

やりたいこと・作るもの

ページを移動しても値が維持(共有)され、ページをリロードしても値が(保持したければ)保持されるという機能の検証。

スクリーンショット 2021-09-05 9.22.30.png

準備

プロジェクトの作成

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で定義します。

_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という値を共有する値としたいと思います。

atoms.js
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情報を表示および編集する機能を実装してみます。

index.js
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では読み取りだけしてみたいと思います。

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を改修

数行追加するだけ。便利。簡単。

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] //追加
});
28
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
17