👀
【Vue3】watch内でリスナー解除時にReferenceErrorが出た時の対処法
Vue.jsのwatchを利用している際に、以下エラーが出た時の対処法です。
ReferenceError: Cannot access 'unwatch' before initialization
概要
watchを利用している際に、watch内でリスナーを解除したい時があると思います。
例えば以下のようにユーザ情報を監視して、undefined
からユーザ情報が格納されたタイミング(ユーザ情報を参照可能になったタイミング)で、何かしらの処理を一度だけ実行したい場合があります。
Sample.vue
const unwatch = watch(user, () => {
const userId = user.value?.uid;
if (!userId) return;
// ユーザIDを用いた何かしらの処理
// リスナー解除
unwatch();
},
{
immediate: true, // 構文解析時に実行
}
);
上記コードを実行すると、以下のようなエラーメッセージが表示されます。
ReferenceError: Cannot access 'unwatch' before initialization
これはwatchのオプションにimmediate: true
を指定した状態で、watch内でリスナー解除をしようとすると発生するエラーです。
解決方法
上記エラーを解決するためには、以下のようにします。
- watchの戻り値を受け取った際に変数宣言するのではなく、事前に変数を宣言しておく
- watch内でunwatchする際に、リスナー解除関数が格納されていることを確認してから実行する
Sample.vue
// ReferenceErrorにならないために宣言
let unwatch = null;
unwatch = watch(user, () => {
const userId = user.value?.uid;
if (!userId) return;
// ユーザIDを用いた何かしらの処理
// unwatchが参照可能な場合に、リスナー解除
// これをやらないとunwatchにリスナー解除関数が格納される前に実行されるので、
// 関数ではありませんというエラーが発生します。
if(unwatch) unwatch();
},
{
immediate: true, // 構文解析時に実行
}
);
Discussion