·
1 min read

Vue Tip: Manually Stop Watcher

Vue Tip: Manually Stop Watcher Image

Vue automatically stops watchers (watch and watchEffect) when the component is unmounted if they are created synchronously in <script setup> or setup().

The following watcher will automatically be stopped if Component.vue is unmounted:

Component.vue
1<script setup>
2import { watchEffect } from 'vue'
3
4watchEffect(() => {})
5</script>

However, if you create a watcher asynchronously, it will not be stopped automatically:

Component.vue
1<script setup>
2import { watchEffect, ref } from 'vue'
3
4const user = ref(null)
5
6fetchUser().then((userResponse) => {
7  user.value = userResponse
8
9  // ⚠️ watchEffect is created asynchronously
10  watchEffect(() => {
11    if (user.value) {
12      // do something with the user
13    }
14  })
15})
16</script>

In this case, you can manually stop the watcher by calling the stop function that is returned by watchEffect:

Component.vue
1<script setup>
2import { watchEffect, ref } from 'vue'
3
4const user = ref(null)
5let unwatch = null
6
7fetchUser().then((userResponse) => {
8  user.value = userResponse
9  unwatch = watchEffect(() => {
10    if (user.value) {
11      // do something with the user
12    }
13  })
14})
15
16const stopWatcher = () => {
17  unwatch()
18}
19</script>

Note

You should prefer creating watchers synchronously and only in rare cases create them asynchronously.

Unstopped watchers can lead to memory leaks and unexpected behavior.

In our example, we could create the watcher synchronously and watch the user ref instead:

Component.vue
1<script setup>
2import { watchEffect, ref } from 'vue'
3
4const user = ref(null)
5
6fetchUser().then((userResponse) => {
7  user.value = userResponse
8})
9
10watchEffect(() => {
11  if (user.value) {
12    // do something with the user
13  }
14})
15</script>

This way, the watcher is automatically stopped and you don't need to worry about stopping the watcher yourself.

If you liked this Vue tip, follow me on X to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter:

I will never share any of your personal data. You can unsubscribe at any time.