Vue 3: Ref vs Reactive

Edited to make that question more understandable for future readers

I’ve been trying out the composition API of Vue 3 lately and had a hard time understanding the key difference between ref and reative

Basically const count = ref(0) vs const state = reactive({ count: 0 })

Reactive:

Takes an object and returns a reactive proxy of the original.

Ref:

Takes an inner value and returns a reactive and mutable ref object. The ref object has a single property .value that points to the inner value.

Both are reactive and both can interact with the html template–interpolation syntax for instance. I’ve been wondering, what’s the key difference?

Source: https://vue-composition-api-rfc.netlify.com/

You can’t use reactive() on primitives (strings, numbers, booleans) - that’s what you need refs for, because you will have situations where you need to have a “reactive boolean”, for example…

of course your can create an object that wraps the primitive value and make that reactive():

const wrappedBoolean = reactive({
  value: true
})

and just like that, you reinvented a ref

2 Likes

First of all, thank you so much for your answer.

However, in the current API you might would do the following:

data () { return { value: true } }

and this could be equally to this:

setup () { return { ...reactive({ value: true }) } }

So, there wouldn’t be a difference, right?

I understand that wrapping one primitive value within an object isn’t that useful and I should consider using ref then, but if I have multiple values, then I rather use the reactive function, shouldn’t I?

Not quite. re-writing your last statement a bit, this is what you actually did:

setup () { 
  return {
    value: true
  } 
}

by spreading th ractive object you broke reactivity. You returned a static, nonreactive value.

Not necessarily.

You can always use refs (and a lot of people I spoke to chose to do that for consistency, as well as myself), while you can’t always use reactive - sometimes you just need to deal with refs: Computed properties return refs, for example. Template refs only work with refs. Passing a reactive value to another function and keep reactivity only works with a ref. Replacing an object with a new version from the backend works much better and cleaner with a ref.

So the essence is that yes, you can group multiple values in a reactive object if you like that style better. But you still will have to work with refs quite a lot.

2 Likes

JavaScript should have refs built in hey :wink:

In addition to all new visitors of this post:

The documentation of the vue-composition API has already explained what’s the difference

Source: https://vue-composition-api-rfc.netlify.com/#ref-vs-reactive

I somehow overlooked that. So a combination of this and the answer of @LinusBorg should make you understand the difference.

A good final answer to this would actually be a quote

At this stage, we believe it is too early to mandate a best practice on ref vs. reactive. We recommend you to go with the style that aligns with your mental model better from the two options above. We will be collecting real world user feedback and eventually provide more definitive guidance on this topic

It’s really not easy to say which is better as it’s somehow depends on the coding style you are used to.

Not mentioned here but you could basically just use reactive() all the time as there is a method toRefs which transforms the reactive object to ref

const pos = reactive({
    x: 0,
    y: 0
  })

  // ...
  return toRefs(pos)