【jotai】App Routerでの状態管理
TL;DR
- App RouterでRecoilを使用するにはコツが必要そう
- jotaiを使用すると、App RouterでもPages Routerと同様に状態管理ができて、スムーズ
問題意識
僕は日頃Recoil使用者でRecoilをしようすることが多いです。App RouterでのアプリケーションでもRecoilを使用する予定でした!
なので、ウキウキでApp Routerでのアプリケーションに Recoilを取り込んでみたんです!しかい、うまくいきませんでした。。
Pages RouterでRecoilを利用する場合、状態管理を行うコンポーネントを<Recoil Root />
で囲ってあげる必要があり、よくある手段として、_app.tsx
にて、childrenを<RecoilRoot />
で囲ってあげると思います。
これをApp Routerのlayout.tsx
で行おうとすると、「サーバーコンポーネントには<RecoilRoot />
は置けないよ!」とランタイムに怒られます。。
では、layout.tsx
に'use client'
をつけて、サーバーコンポーネントではなく、クライアントコンポーネントにすればよいのか?というと、そうではないです。(※コンポーネントにuse client
をつけると、サーバーコンポーネントではなく、サーバーコンポーネントとして取り扱われるようになります。)
なぜならlayout.tsx
にuse client
をつけると、下の階層(URLパス・子コンポーネントの両方)のすべてのコンポーネントがクライアントコンポーネントとして認識されてしまい、App Routerの恩恵を享受することができないからです。
結論
jotai を使用すると、Pages Router と同じ感覚で、状態管理を行うことが可能なので、jotaiを使うと状態管理がスムーズになる。
確認したこと
個人的には、「別のサーバーコンポーネント内にあるクライアントコンポーネント同士でも状態管理ってできるの?」というところでした。
なので、下記のような構成で状態管理を確認しました。
page
├ ServerComponentA
| └ ClientComponentA
└ ServerComponentB
└ ClientComponentB
結果として、👇のような動作となり、無事に「別のサーバーコンポーネント内にあるクライアントコンポーネント同士でも状態管理ってできるの?」への回答がYESであることを確認しました!
こちらの動作確認を行ったソースコードは👇のリポジトリに格納しております。気になる方がいらっしゃれば、ご覧ください。
最後に
この記事は「Recoilではなく、jotaiを使おう」ということを言いたい記事ではありません。僕自身、本当にRecoilがApp Routerに合わないのかを調べ切っていません。
あくまで、「いまからアプリケーションを作成し、状態管理を行うならば、jotaiを使うと、スムーズに状態管理を始められる可能性が高いです。」ということが言いたい次第でした。
逆に、Recoilでスムーズに使う方法があれば、その方法も知りたいなというのが僕の思いです…!
もし、お気づきの点等あれば、ご教示いただけますと幸いです!
最後までお読みいただき、ありがとうございました!🙇
Discussion
細かすぎる指摘 && 意図の読み間違いかもしれない で恐縮ですが、僕の記憶が正しければ、layout.tsx は composition パターンで実装されているので、 page.tsx 側には
'use client';
が波及しないはずです。もちろん layout.tsx から(children ではなく) 直接利用しているコンポーネントには
'use client';
の影響がおよぶので、避けたほうが良いと思いますが。