0Pricing
Vue Academy · Lesson

ref vs reactive: When to Use Each

ref.value access, reactive unwrapping in templates, toRefs(), toRef() for destructuring.

ref vs reactive: When to Use Each is a free Vue Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Two Reactivity Tools

Vue offers two main ways to create reactive state: ref() and reactive(). They overlap, but each fits certain situations better. Knowing when to reach for which keeps your code clean.

ref Works with Any Value

ref() can wrap anything: a number, string, boolean, array, or object. The value lives on .value in JavaScript.

import { ref } from 'vue'

const count = ref(0)
const name = ref('Alice')
const isOpen = ref(false)

count.value++
name.value = 'Bob'

ref Auto-Unwraps in Templates

While you must write .value in JavaScript, the template auto-unwraps a top-level ref. So {{ count }} just works.

<!-- template -->
<p>{{ count }} - {{ name }}</p>

reactive Is for Objects

reactive() only accepts objects (including arrays and Maps). It returns a deeply reactive proxy and you access properties directly — no .value.

import { reactive } from 'vue'

const state = reactive({
  name: 'Alice',
  age: 30,
  hobbies: ['reading']
})

state.age = 31
state.hobbies.push('coding')

reactive Is Deeply Reactive

Nested objects and arrays inside a reactive object are also reactive. Mutating a nested property triggers updates without extra work.

const state = reactive({ profile: { city: 'Paris' } })
state.profile.city = 'Berlin' // reactive!

The reactive Limitation: Destructuring Breaks It

If you destructure a reactive object, the extracted variables become plain values and lose reactivity. This is the number one gotcha.

const state = reactive({ name: 'Alice' })
let { name } = state
name = 'Bob'
// state.name is still 'Alice' - reactivity lost!

The Fix: toRefs for Safe Destructuring

toRefs() converts each property of a reactive object into a ref. Now you can destructure and keep reactivity, because each piece is a ref linked back to the source.

import { reactive, toRefs } from 'vue'

const state = reactive({ name: 'Alice', age: 30 })
const { name, age } = toRefs(state)
name.value = 'Bob' // state.name is now 'Bob'

toRef for a Single Property

If you only need one property as a ref, use toRef(state, 'key'). It stays in sync with the source object both ways.

import { reactive, toRef } from 'vue'

const state = reactive({ age: 30 })
const age = toRef(state, 'age')
age.value = 31 // state.age is now 31

A Practical Rule of Thumb

  • Use ref() for primitives (numbers, strings, booleans) and standalone values.
  • Use reactive() for a group of related properties that form one object.
  • When returning a reactive object from a composable, wrap it in toRefs().

ref Can Also Hold Objects

You are not forced to choose reactive for objects. A ref holding an object is also deeply reactive — you just access it through .value. Many teams use ref everywhere for consistency.

const user = ref({ name: 'Alice' })
user.value.name = 'Bob' // reactive
user.value = { name: 'Carol' } // replace whole object

Summary Table

  • ref: any value, needs .value in JS, auto-unwraps in template, can be reassigned wholesale.
  • reactive: objects only, no .value, deeply reactive, but breaks on destructure and cannot be reassigned.
  • toRefs: bridge that makes reactive properties destructurable.

Quick Check

Pick the right tool.

Recap

Key takeaways:

  • ref() wraps any value and needs .value in JavaScript.
  • reactive() is for objects and is deeply reactive, but destructuring breaks it.
  • toRefs() lets you safely destructure a reactive object.
  • Use ref for primitives, reactive for grouped object state.

Frequently asked questions

Is the “ref vs reactive: When to Use Each” lesson free?

Yes — the full text of “ref vs reactive: When to Use Each” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.

What will I learn in “ref vs reactive: When to Use Each”?

ref.value access, reactive unwrapping in templates, toRefs(), toRef() for destructuring. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Vue Academy?

No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “ref vs reactive: When to Use Each” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Vue Academy lesson?

Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Why Composition API?
  2. setup() Function and Reactive Variables
  3. ref vs reactive: When to Use Each
  4. Computed and Watch in Composition API
← Back to Vue Academy