DEV Community

Cover image for Reactive vs. Ref in Vue 3: What’s the difference?
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Reactive vs. Ref in Vue 3: What’s the difference?

Vue 3 introduced the Composition API, offering developers more flexible and powerful tools for managing reactivity in their applications.

Among these tools, reactive and ref are two key methods for creating reactive state. While they may appear similar at first glance, understanding their differences is essential for writing clean and efficient Vue code.

In this article, I would like to list differences between reactive and ref and provides practical examples to help you decide when to use each :)

Enjoy!

🤔 What is ref and reactive?

In order to be able to compare these two Vue 3 utilities, we would need to understand better what they are and how they work.

What is reactive?

reactive is a method provided by Vue 3 that creates a deeply reactive object. It converts an object’s properties into reactive data, meaning any changes to those properties will trigger updates in the UI. The syntax of reactive looks like following:

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  user: {
    name: 'John Doe',
    age: 30
  }
});

state.count++; // Updates the UI
state.user.name = 'Jane Doe'; // Updates the UI
Enter fullscreen mode Exit fullscreen mode

reactive works best with objects including arrays and comes with deep reactivity which means that all nested properties of the object become reactive.

Use reactive when managing complex state that involves objects or arrays. It’s ideal for scenarios where you need to track multiple properties as part of a single state.

What is ref?

ref is another method provided by Vue 3, but it creates a reactive reference to a single value. Unlike reactive, ref is designed to handle primitive data types such as strings, numbers, and booleans, as well as individual objects. The syntax of ref looks like following:

import { ref } from 'vue';

const count = ref(0);
const userName = ref('John Doe');

count.value++; // Updates the UI
userName.value = 'Jane Doe'; // Updates the UI
Enter fullscreen mode Exit fullscreen mode

ref works for primitive values and single objects and comes with a reactive wrapper .value property that provides access to the actual value.

Use ref when managing a single reactive value or when you need reactivity for a non-object type, like a number or string.

🟢 Reactive vs. Ref

Now, that we know what are reactive and ref let's compare them to see what are the differences and use cases:

reactive ref
Purpose Reactive state for objects and arrays Reactive state for single values or objects
API Works directly with the object Requires .value to access or update values
Reactivity Depth Deep reactivity Shallow reactivity
Simplicity Best for managing structured state Best for simple, isolated values

To better understand the differences, let's take a look at the following examples.

Example 1: Reactive Object vs. Ref for Primitive Values

import { reactive, ref } from 'vue';

const reactiveState = reactive({ count: 0 });
const refCount = ref(0);

// Incrementing values
reactiveState.count++; // Directly updates the object property
refCount.value++; // Updates the .value property
Enter fullscreen mode Exit fullscreen mode

Example 2: Reactive Array vs. Ref Array

const reactiveArray = reactive([1, 2, 3]);
const refArray = ref([1, 2, 3]);

reactiveArray.push(4); // Reactivity works on array mutations
refArray.value.push(4); // Need .value for array operations
Enter fullscreen mode Exit fullscreen mode

Example 3: Using Reactive for Nested State

const reactiveUser = reactive({
  profile: {
    name: 'Alice',
    age: 25
  }
});

const refUser = ref({
  profile: {
    name: 'Alice',
    age: 25
  }
});

reactiveUser.profile.age = 26; // Automatically reactive at all levels
refUser.value.profile.age = 26; // Requires .value
Enter fullscreen mode Exit fullscreen mode

Mixing reactive and ref

In real-world applications, you’ll often use reactive and ref together. For example, you might use reactive for managing a complex object and ref for a single state value.

const state = reactive({
  items: [],
  loading: ref(false)
});

state.loading.value = true;
state.items.push({ id: 1, name: 'Item 1' });
state.loading.value = false;
Enter fullscreen mode Exit fullscreen mode

This feature could probably be delivered by only one Vue 3 utility but creators of this amazing frameworks thought about that already and decided to split it to give us more flexibility :)

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

✅ Summary

Both reactive and ref are powerful tools for managing reactivity in Vue 3, but they serve different purposes. Use reactive for structured, complex state and ref for isolated or primitive values. By understanding their differences, you can choose the right tool for the right job, leading to cleaner and more maintainable code.

Experiment with both in your projects to find the balance that works best for your development style.

Take care and see you next time!

And happy coding as always 🖥️

Top comments (0)