Ref vs Reactive

Learn the difference between Ref and Reactive in Vue 3 through examples where you'll discover the pros and cons in each case.


Learning the Vue 3 Composition API đŸ‡Ș🇾 is something that you have to do to get the most out of Vue. However, one of the first questions that will come to mind is what the difference is between ref and reactive when declaring reactive values.

When to use reactive?

If you're coming from the Options API, the best way to understand the reactive function is to see it as the equivalent of the data object.

When we create a reactive object, Vue generates a Proxy of it to control operations on its properties (intercepts get and set). This is important for several reasons.

  1. You can only store composite values with reactive. For example, objects, arrays, maps, sets, etc. In other words, you cannot use reactive with primitive values.
  2. It's not possible to change the reference of a reactive object (or pass one of its properties as a parameter) without losing reactivity. For example, you cannot use destructuring as is.
JS
import { reactive } from "vue"
const user = reactive({ name: "Juan", city: "Valencia" })
let { name } = user // ❌ name no es reactivo
name += " AndrĂ©s" // ❌ no afecta a user.name

If we want to destructure values from a reactive object and make them reactive as well, we can use the toRef and toRefs helpers.

JS
import { toRefs } from "vue"
let { name } = toRefs(user) // ✅ name es reactivo

In summary:

Use reactive when you have a collection of values that need to be reactive. For example, an object with user information, metadata, or form fields. However, remember to stick to composite values and ensure that you always store the reference to the original object to maintain reactivity.

When to use ref?

Vue provides the ref function, and it can store any value inside it (not just primitives, as many might think when starting to work with Vue 3). This makes ref more versatile than reactive.

The ref function creates an object that wraps the reactive value, so —importantly— to access the value, you need to use the value property.

JS
import { ref } from "vue"
const myName = ref("Juan")
myName += " AndrĂ©s" // 🖕
myName.value += " AndrĂ©s" // ✅

However, it's not necessary to use value if we access the reactive reference within the component's template.

<h1>{{ myName }}</h1>

Another difference with reactive is that with ref, you can replace the reference of an object without losing reactivity. In fact, if we create a reactive object with ref, we are essentially using reactive.

JS
import { ref } from "vue"
const user = { name: ref("Juan"), city: ref("Valencia") };
let { name } = user; // ✅ name es reactivo
name.value += " AndrĂ©s"; // ✅ afecta a user.name

In summary:

Use ref when you want to have smaller pieces of state that need to be reactive. For example, a flag indicating whether there is authentication or not (e.g., isAuth), the name of the logged-in user, or the total to pay for a shopping cart. Keep in mind that although ref is more versatile, you will have to use value ( though this might change soon), and if you use it with an object, you're essentially using reactive, with all that it entails.

Juan AndrĂ©s NĂșñez
Juan AndrĂ©s NĂșñez
Frontend Engineer. Vue.js Specialist. Professional Teacher. Stoic.