Bird
Raised Fist0
Vueframework~15 mins

Ref and reactive in Composition API in Vue - Deep Dive

Choose your learning style10 modes available
Overview - Ref and reactive in Composition API
What is it?
Ref and reactive are two ways to create reactive state in Vue's Composition API. Ref wraps a single value and makes it reactive, while reactive creates a reactive proxy for an entire object or array. They let Vue track changes and update the user interface automatically. This helps build dynamic, interactive web apps easily.
Why it matters
Without ref and reactive, developers would have to manually update the UI when data changes, which is error-prone and slow. These tools solve the problem of keeping the UI in sync with data automatically. This makes apps smoother, easier to maintain, and less buggy, improving user experience and developer productivity.
Where it fits
Before learning ref and reactive, you should understand basic JavaScript objects and Vue's template syntax. After mastering them, you can learn advanced state management, Vue's watch and computed APIs, and how to build complex reactive systems.
Mental Model
Core Idea
Ref and reactive wrap data so Vue can watch for changes and update the UI automatically.
Think of it like...
Imagine ref as a single mailbox holding one letter, and reactive as a whole mailbox system holding many letters and packages. Vue checks these mailboxes for new mail to deliver updates.
┌─────────────┐       ┌───────────────┐
│   ref(val)  │──────▶│  reactive UI  │
│  (single)   │       │  updates when │
└─────────────┘       │  val changes  │
                      └───────────────┘

┌─────────────────────┐
│ reactive(object)    │──────▶ reactive UI updates
│ (many properties)   │
└─────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Vue Reactivity Basics
🤔
Concept: Vue tracks changes in data to update the UI automatically.
In Vue, when data changes, the UI updates to reflect those changes without manual DOM manipulation. This is called reactivity. Vue uses special wrappers to watch data and trigger updates.
Result
UI elements change automatically when the underlying data changes.
Understanding that Vue automatically updates the UI when data changes is the foundation for why ref and reactive exist.
2
FoundationWhat is ref in Composition API
🤔
Concept: Ref creates a reactive wrapper around a single value.
Using ref, you wrap a single value like a number or string. Vue tracks this value and updates the UI when it changes. You access the value inside ref with .value. Example: const count = ref(0); count.value = 1; // UI updates automatically
Result
A reactive single value that triggers UI updates when changed.
Knowing that ref wraps a single value and requires .value to access helps avoid confusion and bugs.
3
IntermediateWhat is reactive in Composition API
🤔
Concept: Reactive creates a reactive proxy for an entire object or array.
Reactive wraps an object or array so Vue can track changes to any property inside it. Example: const state = reactive({ count: 0, name: 'Vue' }); state.count = 2; // UI updates automatically You do not use .value here.
Result
A reactive object or array that updates the UI when any property changes.
Understanding reactive lets you manage complex state with many properties easily.
4
IntermediateDifferences Between ref and reactive
🤔Before reading on: Do you think ref can wrap objects as easily as reactive? Commit to your answer.
Concept: Ref is for single values; reactive is for objects and arrays.
Ref wraps any value but is best for primitives or single values. Reactive is designed for objects and arrays and tracks nested properties deeply. Ref example: const message = ref('hello'); Reactive example: const user = reactive({ name: 'Alice', age: 30 });
Result
Choosing the right tool based on data type improves code clarity and performance.
Knowing when to use ref vs reactive prevents bugs and makes your code easier to understand.
5
IntermediateAccessing and Updating Reactive Data
🤔Before reading on: Do you think you access reactive object properties with .value like ref? Commit to your answer.
Concept: Ref requires .value to access; reactive does not.
For ref: const count = ref(0); console.log(count.value); // access count.value = 5; // update For reactive: const state = reactive({ count: 0 }); console.log(state.count); // access state.count = 5; // update
Result
Correct access patterns avoid runtime errors and confusion.
Understanding access differences is key to using Composition API state correctly.
6
AdvancedReactivity Caveats and Limitations
🤔Before reading on: Do you think reactive tracks new properties added after creation automatically? Commit to your answer.
Concept: Reactive does not track new properties added later; ref always tracks its value.
Reactive creates a proxy for existing properties only. Adding new properties later won't be reactive unless you use Vue.set or create the property upfront. Example: const state = reactive({}); state.newProp = 123; // Not reactive Ref always tracks its value changes: const count = ref(0); count.value = 1; // reactive
Result
Knowing this prevents bugs where UI does not update as expected.
Understanding reactive's limitation with new properties helps avoid silent bugs.
7
ExpertRef Unwrapping and Proxy Internals
🤔Before reading on: Do you think Vue unwraps ref automatically inside reactive objects? Commit to your answer.
Concept: Vue unwraps refs inside reactive objects but not in all cases, affecting reactivity behavior.
When you put a ref inside a reactive object, Vue unwraps it so you can access the value directly. Example: const count = ref(0); const state = reactive({ count }); console.log(state.count); // 0, not ref object However, this unwrapping can cause confusion if you expect the ref wrapper. Vue uses proxies to track changes and trigger updates efficiently.
Result
Knowing unwrapping behavior helps write predictable reactive code and debug issues.
Understanding how Vue unwraps refs inside reactive objects clarifies subtle bugs and improves advanced state management.
Under the Hood
Vue uses JavaScript proxies to wrap objects and intercept get and set operations. For ref, Vue creates an object with a .value property and tracks reads and writes to it. For reactive, Vue creates a proxy that intercepts property access and mutations deeply, tracking dependencies. When data changes, Vue triggers updates to components that use that data.
Why designed this way?
Vue's reactivity system was designed to be efficient and intuitive. Using proxies allows Vue to track dependencies without manual subscriptions. Ref was introduced to handle primitive values reactively, which proxies alone can't track. This design balances performance, ease of use, and flexibility.
┌───────────────┐      ┌───────────────┐      ┌───────────────┐
│  User Code    │─────▶│ Vue Proxy or  │─────▶│ Dependency    │
│ (ref/reactive)│      │ Ref Wrapper   │      │ Tracking      │
└───────────────┘      └───────────────┘      └───────────────┘
         ▲                      │                      │
         │                      ▼                      ▼
  ┌───────────────┐      ┌───────────────┐      ┌───────────────┐
  │  Component    │◀─────│  Reactivity   │◀─────│  Data Changes │
  │  Render       │      │  System       │      │  (set, update)│
  └───────────────┘      └───────────────┘      └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do you think reactive tracks new properties added after creation automatically? Commit to yes or no.
Common Belief:Reactive objects track all property changes, including new properties added later.
Tap to reveal reality
Reality:Reactive only tracks properties present when the object is made reactive. New properties added later are not reactive unless handled specially.
Why it matters:Adding new properties without care leads to UI not updating, causing confusing bugs.
Quick: Do you think ref always requires .value to access inside templates? Commit to yes or no.
Common Belief:You must always use .value to access ref values, even inside templates.
Tap to reveal reality
Reality:In Vue templates, ref values are unwrapped automatically, so you can use them directly without .value.
Why it matters:Misunderstanding this leads to verbose or incorrect template code.
Quick: Do you think reactive can wrap primitive values like numbers or strings? Commit to yes or no.
Common Belief:Reactive can wrap any value, including primitives like numbers or strings.
Tap to reveal reality
Reality:Reactive only works with objects and arrays. For primitives, ref must be used.
Why it matters:Using reactive on primitives causes errors or no reactivity, leading to wasted time debugging.
Quick: Do you think ref inside reactive objects behaves exactly like standalone refs? Commit to yes or no.
Common Belief:Ref inside reactive objects behaves exactly like standalone refs, requiring .value access.
Tap to reveal reality
Reality:Vue unwraps refs inside reactive objects, so you access the value directly without .value.
Why it matters:Not knowing this causes confusion and bugs when mixing ref and reactive.
Expert Zone
1
Vue unwraps refs inside reactive objects but not inside arrays, which can cause subtle bugs.
2
Using reactive on large nested objects can impact performance due to deep proxying; selective ref usage can optimize this.
3
Ref can hold objects too, but wrapping objects in ref disables deep reactivity, unlike reactive.
When NOT to use
Do not use reactive for primitive values; use ref instead. Avoid reactive for very large or deeply nested objects if performance is critical; consider using shallowReactive or ref with manual updates. For simple state, sometimes Vue's Options API or external state management libraries may be better.
Production Patterns
In production, developers often use ref for simple counters or flags and reactive for complex state objects. They combine ref and reactive to optimize performance and clarity. They also use watch and computed with ref/reactive to create derived state and side effects.
Connections
Observer Pattern
Ref and reactive implement a form of the observer pattern by tracking dependencies and notifying changes.
Understanding observer pattern principles clarifies how Vue tracks and reacts to data changes.
Functional Programming
Ref and reactive encourage immutable-like patterns by separating state and effects.
Knowing functional programming concepts helps write cleaner reactive code with fewer side effects.
Spreadsheet Cell Dependencies
Like spreadsheet cells updating when dependent cells change, ref and reactive update UI when data changes.
Recognizing this connection helps understand automatic dependency tracking and update propagation.
Common Pitfalls
#1Adding new properties to reactive objects expecting reactivity.
Wrong approach:const state = reactive({}); state.newProp = 'hello'; // UI will NOT update
Correct approach:const state = reactive({ newProp: 'hello' }); // define upfront // or use Vue.set(state, 'newProp', 'hello') in Vue 2
Root cause:Reactive proxies only track existing properties; new properties added later are not reactive.
#2Accessing ref value without .value in JavaScript code.
Wrong approach:const count = ref(0); console.log(count); // logs ref object, not value
Correct approach:const count = ref(0); console.log(count.value); // logs 0
Root cause:Ref wraps value inside .value property; forgetting this causes confusion.
#3Using reactive on a primitive value.
Wrong approach:const num = reactive(5); // does not work as expected
Correct approach:const num = ref(5); // correct reactive primitive
Root cause:Reactive only works with objects and arrays; primitives need ref.
Key Takeaways
Ref and reactive are core tools in Vue's Composition API to create reactive state that updates the UI automatically.
Use ref for single primitive values and reactive for objects or arrays with multiple properties.
Ref requires accessing the value with .value in JavaScript, but Vue templates unwrap refs automatically.
Reactive proxies only track existing properties; adding new properties later is not reactive unless handled carefully.
Understanding Vue's unwrapping of refs inside reactive objects helps avoid subtle bugs in complex state management.

Practice

(1/5)
1. In Vue's Composition API, what is the main difference between ref and reactive?
easy
A. ref is used to create components, reactive is used to create directives.
B. ref is only for arrays, reactive is only for strings.
C. ref is for simple values accessed with .value, reactive is for objects and arrays accessed directly.
D. ref and reactive are exactly the same and can be used interchangeably.

Solution

  1. Step 1: Understand ref usage

    ref holds simple reactive values like numbers or strings and requires accessing the value with .value.
  2. Step 2: Understand reactive usage

    reactive wraps objects or arrays to make their properties reactive and accessed directly without .value.
  3. Final Answer:

    ref is for simple values accessed with .value, reactive is for objects and arrays accessed directly. -> Option C
  4. Quick Check:

    ref vs reactive difference = D [OK]
Hint: Remember: ref = simple value with .value, reactive = object direct access [OK]
Common Mistakes:
  • Thinking ref works directly on objects without .value
  • Confusing reactive as only for primitive values
  • Assuming ref and reactive are interchangeable
2. Which of the following is the correct way to declare a reactive object in Vue 3 Composition API?
easy
A. const state = ref({ count: 0 })
B. const state = reactive({ count: 0 })
C. const state = reactive(0)
D. const state = ref(0)

Solution

  1. Step 1: Identify correct reactive syntax for objects

    reactive is used to wrap objects to make their properties reactive.
  2. Step 2: Check each option

    const state = ref({ count: 0 }) uses ref with an object, which is allowed but requires .value to access. const state = reactive({ count: 0 }) correctly uses reactive with an object. const state = reactive(0) uses reactive with a number, which is invalid. const state = ref(0) uses ref with a number, which is valid but not for objects.
  3. Final Answer:

    const state = reactive({ count: 0 }) -> Option B
  4. Quick Check:

    reactive object syntax = C [OK]
Hint: Use reactive() for objects, ref() for primitives [OK]
Common Mistakes:
  • Using reactive() on primitive values
  • Using ref() for objects without .value access
  • Confusing reactive and ref usage
3. Given the code:
import { ref, reactive } from 'vue';
const count = ref(0);
const state = reactive({ clicks: 0 });

count.value++;
state.clicks++;

console.log(count.value, state.clicks);

What will be logged to the console?
medium
A. 0 1
B. 0 0
C. 1 0
D. 1 1

Solution

  1. Step 1: Understand ref and reactive increments

    count is a ref holding 0, incremented by count.value++ to 1. state is reactive object with clicks 0, incremented by state.clicks++ to 1.
  2. Step 2: Check console.log output

    Logging count.value and state.clicks will print 1 1.
  3. Final Answer:

    1 1 -> Option D
  4. Quick Check:

    Increment ref and reactive values = A [OK]
Hint: Increment ref with .value, reactive directly [OK]
Common Mistakes:
  • Forgetting to use .value with ref
  • Assuming reactive needs .value
  • Mixing up initial values
4. What is wrong with this Vue Composition API code?
import { ref } from 'vue';
const user = ref({ name: 'Alice' });
user.name = 'Bob';
medium
A. You must use user.value.name to update the name property.
B. ref cannot hold objects, use reactive instead.
C. You should use user.value() to access the object.
D. There is no error; the code works fine.

Solution

  1. Step 1: Understand ref with objects

    ref wraps the object, so to access or update properties inside, you must use .value.
  2. Step 2: Identify the error in property update

    The code tries to update user.name directly, which is incorrect. It should be user.value.name.
  3. Final Answer:

    You must use user.value.name to update the name property. -> Option A
  4. Quick Check:

    Access ref object properties with .value = A [OK]
Hint: Use .value to access or update ref object properties [OK]
Common Mistakes:
  • Accessing ref object properties without .value
  • Confusing ref and reactive usage
  • Thinking ref cannot hold objects
5. You want to create a reactive state for a form with fields name (string) and tags (array). You also want to track a simple counter for submissions. Which setup correctly uses ref and reactive together?
hard
A. const form = reactive({ name: '', tags: [] }); const submitCount = ref(0);
B. const form = ref({ name: '', tags: [] }); const submitCount = reactive(0);
C. const form = reactive(''); const submitCount = ref([]);
D. const form = ref(''); const submitCount = reactive({ count: 0 });

Solution

  1. Step 1: Identify correct usage for form object

    The form has multiple fields, so reactive is best to wrap the object with name and tags properties.
  2. Step 2: Identify correct usage for simple counter

    The submission count is a simple number, so ref is appropriate to track it reactively.
  3. Final Answer:

    const form = reactive({ name: '', tags: [] }); const submitCount = ref(0); -> Option A
  4. Quick Check:

    Use reactive for objects, ref for simple values = B [OK]
Hint: Use reactive for objects/arrays, ref for simple values [OK]
Common Mistakes:
  • Using ref for complex objects without .value
  • Using reactive on primitive values
  • Mixing up which data needs ref or reactive
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard