Recoil の開発がストップした
私の開発している議事録管理ツール「ワンミニッツ」では、フロントエンドに Next.js を使っており、グローバルな状態管理に Recoil を使っています。
しかし、Recoil は 2025年1月に GitHub のリポジトリがアーカイブされ、更新が停止されました。Recoil は Facebook が開発したライブラリですが、社内にメンテナーがいなくなったことによりメンテナンスが終了したようです。以下の記事が非常に詳しく書いています。
そこで、Recoil に変わる、グローバル状態管理ライブラリを入れることにします。
グローバルな状態管理とは
React の状態管理は基本的に useState
を使いますが、これはコンポーネント内で状態を管理するのが主な使い方です。親子のコンポーネントの間で状態のやり取りはできるのですが、
- 親子関係が複雑になるとバケツリレーが大量に発生する
- 親子の依存関係が強くなり、コンポーネントの再利用性が低くなってしまう
などのデメリットがあります。
そこで、多くのコンポーネントで使われる状態は、グローバルな状態管理にしたほうがわかりやすくなります。
Recoil の代わりとなるライブラリの候補
Redux
Redux は昔からある状態管理のツールです。僕も昔に Redux を触ったことがありますが、学習コストが高いです。Redux に対して、学習コストが低い Recoil などが登場してきて、皆そちらに流れていったイメージです。
今回は採用しないことにしました。理由は以下の通り
- 学習コストの高さ
- 現在利用している Recoil とはアーキテクチャが違いすぎる
React Context
React には Context という機能があります。ただ、React Context は、コンポーネントのバケツリレーをなくすためのものであり、グローバルな状態管理とは少し違う気がします。そのため、状態の更新は自前でなんとか実装しないといけないし、コンポーネントの親子関係の依存が残ってしまうのは変わらないです。
Jotai
Jotai は使い勝手としては Recoil に近いと思いますが、次に紹介する SWR を採用したため、今回は採用しませんでした。
SWR
SWR は Vercel が開発したライブラリです。Next.js を開発している Vercel が開発しているということで、それなりに信頼感はあります。
SWR はもともとはデータをいい感じにキャッシュするためのライブラリのようですが、グローバルな状態管理にも使えます。
通常の使い方はこんな感じです。
import useSWR from 'swr' const fetcher = () => // API を叩いたりしてデータを取得する const { data, mutate } = useSWR('cacheKey', fetcher)
まずは fetcher
という関数を用意します。fetcher の中では、API を叩いてデータを取得する処理を書きます。useSWR
にキャッシュのキーと fetcher を渡すと、データを取得してキャッシュに保存したうえで、data 変数に fetcher の結果が入ります。
キャッシュのキーはグローバルで、同じ cacheKey で useSWR を呼ぶと、fetcher は呼ばれずに、キャッシュされているデータが返ってきます。
mutate()
関数を呼ぶと、 fetcher が実行されてキャッシュが更新されます。API を叩いて取得したデータを色んなコンポーネントで利用する場合、毎回 API を呼ぶことなく、キャッシュから取得してくれますし、データに更新が合った時は mutate() を呼べば一斉に更新できるので、非常に便利です。
SWR を単なる状態管理として使う場合
fetcher に null を指定すると、単なるグローバル状態管理となります。initialData を渡すこともできます。
mutate メソッドに引数を渡すことで、状態の更新ができます。
const { data, mutate } = useSWR('cacheKey', null, { initialData: 'Hoge' }); // 値を更新 mutate('Fuga')
まとめ
Recoil が更新停止したため、SWR に以降することにしました。
状態更新ライブラリは以下の記事が非常によくまとまっているので参考にしてみてください。