Ref vs Reactive


Vue 3’s Composition API provides two main ways of declaring reactive data: ref and reactive. What’s the difference between these and which should you use?

This tutorial will cover the following:

  • What’s ref?
  • What’s reactive?
  • What are the pros and cons of each?
  • When should you use ref vs reactive?

What is ref?

To create a single reactive variable with the Composition API you can use ref.

You can initialize a ref with any JavaScript primitive e.g. String, Number, Object, etc.

const count = ref(0);

Since count is a reactive variable, changing its value in JavaScript will cause a re-render of the component.

Make sure you have opened the Preview window of the code editor.

Then press the "Increment" button and you’ll see the value of count increases. This is because it is incremented by the button click handler (line 16).

ref value property

Note that ref returns an object. The reactive data is available through the .value property.

const count = ref(0)
count === 0 // false
count.value === 0 // true

A big “gotcha” with ref is that accessing the value in JavaScript is different to accessing it in the template.

In the template, the value property is implied - you don't need to specify it.

<h1>{{ count.value }}</h1> <!--incorrect-->
<h1>{{ count }}</h1> <!--correct-->

In the code editor, we've moved the click handler into a method increment and out of the template.

Note that this method uses count.value not count like we did in the template.

const increment = () => {
  count.value++
}

What is reactive?

reactive is another Composition API method used for declaring reactive data.

Unlike ref, reactive can only be initialized with an object. Each property of the object can be a different reactive variable, however.

const data = reactive({
  count: 0,
  name: 'Peter Griffin',
  flag: false
})

One advantage of reactive is that it doesn’t use a value property so it may be a little easier to read.

data.name === 'Peter Griffin' // true
data.name.value === 'Peter Griffin' // false

It also means it looks the same in JavaScript as in the template.

console.log(data.name) // 'Peter Griffin'
<h1>{{ data.name }}</h1> <!--Peter Griffin-->

Don't destructure reactive

The big "gotcha" of reactive is that may tempt you to destructure the object, especially if it's being returned from a function in another file.

You shouldn't do this as the destructured value will not be reactive.

// Wrong
let { count } = data
count++

// Right
data.count++

In the code editor, you'll notice the "Increment" button doesn't work. Can you fix it?

ref or reactive?

The big question is: should you use ref or reactive?

There are advantages to both:

ref advantages:

  • Much easier to pass single variables around your app
  • Avoids destructuring pitfall

reactive advantages:

  • Can be less verbose if declaring lots of reactive variables
  • Consistency between JavaScript and template
  • Similar to Vue 2’s data object

My personal opinion is that the best option is to just use one or the other! This is because I prefer to have one consistent pattern for reactive data in a code base, even if I occasionally miss out on the convenience that the two different methods provide.

I normally use ref as I find it more flexible.


Anthony Gore

About Anthony Gore

I'm Anthony Gore and I'm a web developer with a crush on Vue.js. I'm a Vue Community Partner, curator of the weekly Vue.js Developers Newsletter, and the creator of Vue.js Developers.

If you enjoyed this article, show your support by buying me a coffee. You might also enjoy taking one of my online courses!

Click to load comments...