📚

【React】Expectation Violation: Duplicate atom key "~".errorを解消する方法

2023/01/17に公開

React Fast Refreshを使用している環境で開発中に以下のerrorが表示された。

Expectation Violation: Duplicate atom key "hogehoge".
This is a FATAL ERROR in
production. But it is safe to ignore this warning if it occurred because of hot module replacement.

React Fast RefreshとはNext.jsやViteなどで使用されている技術です。
簡潔に説明をするとHot Reloadのようにファイルが変更される度にブラウザの表示が更新されます。

参考サイト
https://nextjs.org/docs/basic-features/fast-refresh
https://ja.vitejs.dev/guide/features.html#hot-module-replacement

なぜこのerrorが発生したのか

Recoilのissue commentから引用
https://github.com/facebookexperimental/Recoil/issues/733#issuecomment-729255961

Next.jsには、Pagesという概念があります。AdminとClient Appのように、複数のエントリーポイントを持つSPAがあり、どちらもRecoilアトムを宣言したモジュールをインポートしていると想像してください。
開発では、ファイルが変更されると、Next.jsは該当するページエントリーファイルを再ビルドします。
同じNode.jsのプロセスなので、アトムはすでに宣言されています。
基本的に、このチェック/警告を無効にするコンフィギュレーション設定を提供する以外に、この問題を解決する方法は思いつきません。

つまり、作成したatomを別のエントリーポイントから生成するかファイルを変更した際のビルドでもう一つのatomを構築してしまい、keyが重複してしまうとのこと。
上記はNext.jsに限らず複数のエントリーポイントを扱う環境も該当しそうです。

解決した方法

幸いなことにRecoil0.7.6で修正が加わっているため、記載されているRecoilEnvオブジェクトを使用する。
https://recoiljs.org/ko/blog/

対応する手順は以下の通り

  1. 環境変数として設定する
RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false
  1. Recoilを宣言しているファイルで設定する
import { RecoilEnv } from 'recoil';
RecoilEnv.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED = false;

今回私はViteで開発していたため、後者の方法で解決しました。
最後にこの対応の注意点についてですが、error自体はなくせるものの正当なチェックが無効化されてしまうため、本番環境で思わぬerrorが出ないようlocalでのみ設定するなど適切に扱う必要がありそうです。

Discussion