DEV Community

Pravin Jadhav
Pravin Jadhav

Posted on

Understanding Vue.js Lifecycle Hooks vs React’s useEffect

When building interactive web applications, handling side effects is crucial. React’s useEffect and Vue’s lifecycle hooks both serve this purpose, but they do so in different ways. In this blog post, we’ll explore how these mechanisms work, compare their features, and look at practical examples to understand their differences and similarities.

What is a Side Effect?

A side effect is any operation that interacts with the outside world or affects a component beyond rendering. Common examples include:

  • Fetching data from an API
  • Directly manipulating the DOM
  • Setting up subscriptions or timers

React uses useEffect for this, while Vue employs lifecycle hooks and reactive watchers.

React’s useEffect: The Go-To for Side Effects

React’s useEffect is a versatile hook that manages side effects:

import { useState, useEffect } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("Component mounted or count changed:", count);

    return () => {
      console.log("Cleanup before re-run or unmount");
    };
  }, [count]); // Runs on mount and when 'count' changes

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Key Points about useEffect

  • Dependency Array: Controls when the effect runs. Empty ([]) means run only once; dependencies (e.g., [count]) mean run when they change.
  • Cleanup Function: Runs before the next effect or when the component unmounts, ideal for cleaning up timers, subscriptions, etc.

Vue’s Lifecycle Hooks: Structured and Simple

Vue organizes side effects into specific lifecycle hooks:

  • onMounted: Runs after the component is added to the DOM (similar to useEffect(() => {}, []) in React).
  • onUpdated: Runs after reactive data changes cause a re-render (like useEffect with dependencies).
  • onUnmounted: Runs before the component is removed from the DOM (similar to useEffect cleanup).

Vue Composition API Example

import { ref, onMounted, onUpdated, onUnmounted } from 'vue';

export default {
  setup() {
    const count = ref(0);

    onMounted(() => {
      console.log("Vue: Component Mounted");
    });

    onUpdated(() => {
      console.log("Vue: Component Updated", count.value);
    });

    onUnmounted(() => {
      console.log("Vue: Component Unmounted");
    });

    const increment = () => count.value++;

    return { count, increment };
  },
  template: `
    <div>
      <p>Vue Count: {{ count }}</p>
      <button @click="increment">Increment</button>
    </div>
  `
};
Enter fullscreen mode Exit fullscreen mode

watchEffect in Vue: A Closer Alternative to useEffect

Vue’s watchEffect automatically tracks reactive dependencies and re-runs when they change, resembling useEffect.

import { ref, watchEffect } from 'vue';

export default {
  setup() {
    const count = ref(0);

    watchEffect(() => {
      console.log("Count changed:", count.value);
    });

    return { count };
  },
  template: `<div>{{ count }}</div>`
};
Enter fullscreen mode Exit fullscreen mode

Key Differences

Feature React (useEffect) Vue (Lifecycle Hooks & watchEffect)
Runs once on mount ✅ (useEffect(() => {}, [])) ✅ (onMounted)
Tracks dependencies automatically ❌ No ✅ Yes
Cleanup on unmount ✅ Cleanup function ✅ (onUnmounted)
Watches specific variables ✅ With dependency array ✅ (watch)

Practical Example: Fetching Data

React

import { useEffect, useState } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(json => setData(json));
  }, []);

  return <div>{data ? data.title : 'Loading...'}</div>;
}
Enter fullscreen mode Exit fullscreen mode

Vue

import { ref, onMounted } from 'vue';

export default {
  setup() {
    const data = ref(null);

    onMounted(() => {
      fetch('https://api.example.com/data')
        .then(response => response.json())
        .then(json => data.value = json);
    });

    return { data };
  },
  template: `<div>{{ data ? data.title : 'Loading...' }}</div>`
};
Enter fullscreen mode Exit fullscreen mode

Conclusion

React’s useEffect is powerful but can become complex with dependencies and cleanup. Vue’s lifecycle hooks and watchEffect provide a more organized and declarative approach, leveraging Vue’s reactivity system to simplify side effect management. Both frameworks offer robust tools for developers—choosing between them depends on your project’s needs and your familiarity with each system.

Do you prefer React’s flexibility or Vue’s structured simplicity for managing side effects? Let us know in the comments!

Top comments (0)