🙆‍♀️

状態管理ライブラリ Joutai を試してみる in Next.js

2022/08/06に公開

最近 Next.js を触っているのですが、Joutai という状態管理ライブラリが良さそうなので少し動作確認してみました。

https://jotai.org/

実行環境

  • Windows バージョン
エディション	Windows 11 Home
バージョン	21H2
インストール日	‎2022/‎07/‎24
OS ビルド	22000.832
エクスペリエンス	Windows 機能エクスペリエンス パック 1000.22000.832.0

動作確認

1. プロジェクトを作成

npx create-next-app Joutai-starter --typescript
cd Joutai-starter

2. joutai のインストール

npm install jotai

3. プロジェクトファイル

状態は別ファイルに分けます。
atomWithHash() を用いると URL クエリパラメータでも状態保持できるようですので、そちらも一緒に試してみます。

components/atoms/index.tsx
import { atom, PrimitiveAtom } from 'jotai';
import { atomWithHash } from 'jotai/utils';

type get = (_: PrimitiveAtom<number>) => number;

export const countAtom = atomWithHash('count', 0);
export const countMinusAtom = atom<number>((get: get) => get(countAtom) * -1);

メイン画面にはカウンターを設置します。
カウンター表示の <p> タグには後に記載しているエラー対策として suppressHydrationWarning を指定しています。

pages/index.tsx
import { useAtom } from 'jotai';
import type { NextPage } from 'next';
import { countAtom, countMinusAtom } from '../components/atoms';

const Home: NextPage = () => {
    const [countState, setCountState] = useAtom(countAtom);
    const [countMinusState] = useAtom(countMinusAtom);

    return (
        <div>
            <p suppressHydrationWarning>countState: {countState}</p>
            <p suppressHydrationWarning>countMinusState: {countMinusState}</p>
            <button onClick={() => setCountState((c) => c + 1)}>Count Up !</button>
        </div>
    );
};

export default Home;

4. CSR 動作確認

まずは、CSR (Client Side Redering) で動作確認をしてみます。
Count Up ボタンを押すと、URL に #count=xxx の形でパラメータが乗っていますね!

#count=10 と URL を直接書き換えると画面に反映されることも確認しました。
これは便利ですね!

ただ、カウンター表示の <p> タグに suppressHydrationWarning をしていない状態で F5 で更新をかけると次のようなエラーが出ます。


これは不具合なのか仕様なのかはちょっと分からないですが、開発環境でしか発生しないようなので、suppressHydrationWarning を付けることで凌げそうです。

5. SSR 動作確認

次にコードを追加して、SSR (Server Side Rendering) で動作確認をしてみます。

pages/index.tsx
import { useAtom } from 'jotai';
import type { GetServerSideProps, NextPage } from 'next';
import { countAtom, countMinusAtom } from '../components/atoms';

type TParams = {};
export const getServerSideProps: GetServerSideProps<TParams> = async () => {
    return {
        props: {},
    };
};

const Home: NextPage = () => {
    const [countState, setCountState] = useAtom(countAtom);
    const [countMinusState] = useAtom(countMinusAtom);

    return (
        <div>
            <p suppressHydrationWarning>countState: {countState}</p>
            <p suppressHydrationWarning>countMinusState: {countMinusState}</p>
            <button onClick={() => setCountState((c) => c + 1)}>Count Up !</button>
        </div>
    );
};

export default Home;

結果は重複するので掲載しませんが、こちらも同様に機能する結果となりました。
ただ、やはり suppressHydrationWarning がないとエラーにはなりますね。

まとめ

ということで、非常にシンプルに状態管理を実装できて URL パラメータとして応用も出来そうなので今のところ非常に好印象なライブラリです。次に Next.js を実装する際は積極的に取り入れてみたいと思いました。

Code

上記で試したコードは下記に置いています。

https://github.com/Fehde/Jotai-starter.git

参考 (感謝です!)

https://zenn.dev/tell_y/articles/7a5bd147d34ec2
https://qiita.com/ItsukiN32/items/c87b06dcab1b1383300c

Discussion