Ref vs Reactive - How Vue 3 Declares Reactive Data
Tags: webdev, javascript, vue, programming
Published: 2023-02-15 15:43:22

In Vue3, reactive data can be declared in two ways using **ref()** and **reactive()** functions.

```javascript
const count = ref(0)
const state = reactive({count: 0})
```
This article will help you understand the difference between ref and reactive data declaration in Vue and when to use them.

The ref and reactive functions provided by the Vue3 Composition API are used to create reactive data objects that can be tracked so that changes made to their properties will trigger a re-render of any component that depends on those properties.

The primary difference between ref and reactive is the way they are used to create reactive objects. Ref stores both primitive(string, number, boolean, undefined, null) and objects, Reactive only stores object. Also, data stored in ref can be reassigned while reactive data cannot be reassigned. 

Attempt on reassigning the object stored in reactive will throw a TypeError. You can only assign a new property to the object


```javascript
<script lang="ts" setup>
import { ref, reactive } from 'vue'

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

state.value = {age: 13} ✅
quantity = {age: 13} ❌ 

quantity.age = 13 ✅
</script>
```

![TypeError from reassigning a new object to the quantity object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d48yelrqtnay08f1i3yq.png)

**Reactive**

The **reactive()** function is used to create a reactive object with multiple properties. The function returns a **reactive proxy object** that contains the properties you passed in. If you need to track multiple properties of an object use Reactive.

```javascript
<script lang="ts" setup>
import { reactive } from 'vue'

const count = reactive(0) ❌ 
const state = reactive({
  count: 0,
  message: 'Hello, World!'
}) ✅

// reading a property
console.log(state.count) // 0

// updating a property
  state.count += 1
</script>
```

Reactive is limited in it's application, it can't be used to store primitive data types, it only stores object data types. When you try to store a primitive data, it doesn't track the changes. and updating will throw an error. 


![code image of storing a number to reactive](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5buk2q2ctavu0awdawpd.png)

![code image of increasing the quantity variable ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq04fe7x121ptj8t8fio.png)

Another limitation of the **reactive()** function is it doesn't keep track of the destructured data from the object.

```javascript
import { reactive } from 'vue'
const user = reactive({ name: "Ray", age: 24 })
// destructuring
const {name, age} = user

const changeUsername () => {
 user.name = "Alen"
}

<template>
  <div class="">
    <button @click="changeUsername">change name</button>
    <h1 class=""> {{ name}} </h1> 
    <p class=""> {{ user.name}} </p>
  </div>
</template>
```

The name in the h1 tag will still remain Ray when you click on the button, while the p tag will update to Alen. 

To address the limitations of the **reactive()** function, the **ref()** function was provided. 

**Ref**

**ref** is used for tracking a single value, such as a number, string, or boolean and also objects. When you use the ref() function, it uses the reactive function to create a reactive object under the hood, but it adds an extra layer of indirection to make it possible to get and set the value directly using .value.

```javascript
import { ref } from 'vue'

const count = ref(0) ✅
const user = ref({name: bimpe})  ✅

// reading the value
console.log(count.value) // 0
console.log(user.value.name) // bimpe

// updating the value
count.value += 1
```

Note: accessing the value of count in your template is done without the .value.

```javascript
<template>
    <h1>{{ user.name}}</h1>
    <p>{{ count}}</p>
</template>
```
 
When should you use ref or reactive. Depending on what you are trying to achieve, keep in mind that data stored in ref can be reassigned, so you want to use ref when working with primitives or object you want to reassign. Use reactive when working with objects and want to avoid the overhead of ref.

**Glossary**

**Reactive proxy objects** in Vue are special wrappers around your JavaScript object that allows you to modify their properties and track changes. 

**References**
https://vuejs.org/guide/extras/reactivity-in-depth.html
https://vuejs.org/guide/essentials/reactivity-fundamentals.html#declaring-reactive-state