👶

【jotai】App Routerでの状態管理

2023/05/21に公開1

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.tsxuse clientをつけると、下の階層(URLパス・子コンポーネントの両方)のすべてのコンポーネントがクライアントコンポーネントとして認識されてしまい、App Routerの恩恵を享受することができないからです。

結論

jotai を使用すると、Pages Router と同じ感覚で、状態管理を行うことが可能なので、jotaiを使うと状態管理がスムーズになる。

確認したこと

個人的には、「別のサーバーコンポーネント内にあるクライアントコンポーネント同士でも状態管理ってできるの?」というところでした。

なので、下記のような構成で状態管理を確認しました。

page
├ ServerComponentA
|  └ ClientComponentA
└ ServerComponentB
   └ ClientComponentB

結果として、👇のような動作となり、無事に「別のサーバーコンポーネント内にあるクライアントコンポーネント同士でも状態管理ってできるの?」への回答がYESであることを確認しました!

study-jotai

こちらの動作確認を行ったソースコードは👇のリポジトリに格納しております。気になる方がいらっしゃれば、ご覧ください。

https://github.com/ayakaki/study-jotai-in-approuter

最後に

この記事は「Recoilではなく、jotaiを使おう」ということを言いたい記事ではありません。僕自身、本当にRecoilがApp Routerに合わないのかを調べ切っていません。

あくまで、「いまからアプリケーションを作成し、状態管理を行うならば、jotaiを使うと、スムーズに状態管理を始められる可能性が高いです。」ということが言いたい次第でした。

逆に、Recoilでスムーズに使う方法があれば、その方法も知りたいなというのが僕の思いです…!

もし、お気づきの点等あれば、ご教示いただけますと幸いです!

最後までお読みいただき、ありがとうございました!🙇

Discussion

Honey32Honey32

なぜならlayout.tsxにuse clientをつけると、下の階層(URLパス・子コンポーネントの両方)のすべてのコンポーネントがクライアントコンポーネントとして認識されてしまい、App Routerの恩恵を享受することができないからです。

細かすぎる指摘 && 意図の読み間違いかもしれない で恐縮ですが、僕の記憶が正しければ、layout.tsx は composition パターンで実装されているので、 page.tsx 側には 'use client'; が波及しないはずです。

もちろん layout.tsx から(children ではなく) 直接利用しているコンポーネントには 'use client'; の影響がおよぶので、避けたほうが良いと思いますが。