JAVASCRIPT

Efficient Reactive Side Effects with Vue 3's `watchEffect`

Discover `watchEffect` in Vue 3 for automatically re-running a side effect whenever its reactive dependencies change. It's a powerful alternative to `watch` for simpler, auto-tracking scenarios.

<template>
  <div>
    <h2>User Profile</h2>
    <input type="text" v-model="firstName" placeholder="First Name" />
    <input type="text" v-model="lastName" placeholder="Last Name" />
    <p>Full Name: {{ fullName }}</p>
    <p>Logs updated name in console (check console).</p>
  </div>
</template>

<script setup>
import { ref, watchEffect, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

const fullName = computed(() => `${firstName.value} ${lastName.value}`);

// watchEffect automatically tracks firstName and lastName
watchEffect(() => {
  console.log(`User's full name changed to: ${firstName.value} ${lastName.value}`);
  // This effect will re-run whenever firstName or lastName changes.
});

// Example with cleanup
const userId = ref(1);
watchEffect((onInvalidate) => {
  console.log(`Fetching data for user ID: ${userId.value}`);
  const abortController = new AbortController();
  fetch(`https://jsonplaceholder.typicode.com/users/${userId.value}`, { signal: abortController.signal })
    .then(response => response.json())
    .then(data => console.log('Fetched user:', data.name))
    .catch(error => {
      if (error.name === 'AbortError') {
        console.log('Fetch aborted for user ID:', userId.value);
      } else {
        console.error('Fetch error:', error);
      }
    });

  // Cleanup logic for previous effect run
  onInvalidate(() => {
    abortController.abort();
    console.log(`Cleanup: Aborting fetch for user ID: ${userId.value}`);
  });
});

// You can change userId to see cleanup in action
// setTimeout(() => userId.value = 2, 2000);
</script>
How it works: `watchEffect` simplifies common reactive scenarios by automatically tracking any reactive state accessed within its callback, re-running the effect whenever that state changes. This makes it ideal for synchronizing state, logging, or performing cleanup operations without explicitly listing dependencies. The `onInvalidate` callback provided to `watchEffect` is crucial for cleaning up side effects (like pending API requests or timers) before the effect re-runs or the component unmounts, preventing memory leaks and race conditions.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs