Recoil を HMR 環境で使うと Duplicate atom key というメッセージが表示される
Recoil version 0.0.10をHMR(Hot Module Replacement)環境で使うと次のようなメッセージがコンソール上に表示されます。
Duplicate atom key "user_language". This is a FATAL ERROR in
production. But it is safe to ignore this warning if it occurred because of
hot module replacement. undefined
もしこのメッセージが出てきても、WebpackやReact、Next.jsなどHMR及びそれに準じる操作をしている場合は、無視して大丈夫です。
Duplicate atom keyが出る理由
このメッセージはRecoilのatomに設定するキーは一意でなければならないということを知らせています。
import { atom } from "recoil";
const testState = atom({key: 'user_language', default: 0});
このようにatomを定義する時に設定するkeyは一意である必要があります。もしそれが一意でない場合、動作に問題があるため、このようなメッセージで注意を促しています。
しかしながら、HMR環境ではモジュールが置換される度にキーの登録処理が走ってしまうため発生するようです。
下記はその該当するコードになります。
function registerNode<T>(node: Node<T>): RecoilValue<T> {
if (nodes.has(node.key)) {
const message = `Duplicate atom key "${node.key}". This is a FATAL ERROR in
production. But it is safe to ignore this warning if it occurred because of
hot module replacement.`;
// TODO Need to figure out if there is a standard/open-source equivalent to see if hot module replacement is happening:
// prettier-ignore
// @fb-only: if (__DEV__) {
// @fb-only: const isAcceptingUpdate = require('__debug').isAcceptingUpdate;
// prettier-ignore
// @fb-only: if (typeof isAcceptingUpdate !== 'function' || !isAcceptingUpdate()) {
// @fb-only: expectationViolation(message, 'recoil');
// @fb-only: }
// prettier-ignore
// @fb-only: } else {
recoverableViolation(message, 'recoil');
// @fb-only: }
}
nodes.set(node.key, node);
const recoilValue: RecoilValue<T> =
node.set == null
? new RecoilValueClasses.RecoilValueReadOnly(node.key)
: new RecoilValueClasses.RecoilState(node.key);
recoilValues.set(node.key, recoilValue);
return recoilValue;
}
coreに直接記載されているので、現時点(バージョン 0.0.10)ではこのメッセージは無視するしかないですが、コメントにも記載されているように今後修正されると思います。