Perbedaan dan Penggunaan ref vs reactive dalam Reaktivitas Vue.js

Vue 3 hadir dengan Composition API yang memberi cara baru dalam mengelola state aplikasi. Dua fitur utamanya adalah ref dan reactive. Meski keduanya sama-sama berfungsi untuk membuat data menjadi reaktif, banyak pengembang pemula sering bingung kapan sebaiknya menggunakan ref dan kapan menggunakan reactive.

Artikel ini akan mengupas tuntas:

  • Latar belakang reaktivitas Vue
  • Cara kerja internal ref dan reactive
  • Perbedaan utama dengan contoh nyata
  • Studi kasus kombinasi keduanya
  • Tips best practice dalam memilih dan menggunakan

1. Latar Belakang Reaktivitas di Vue

Reaktivitas adalah konsep inti di Vue. Ibaratnya, ketika Anda mengubah sebuah nilai di JavaScript, Vue akan secara otomatis “mendengarkan” perubahan itu dan memperbarui tampilan di layar.

Contoh sederhana tanpa Vue:

let count = 0
document.querySelector('#btn').addEventListener('click', () => {
  count++
  document.querySelector('#text').innerText = count
})

Di Vue, kita tidak perlu repot mengupdate DOM secara manual, karena Vue menangani sinkronisasi data dan tampilan untuk kita. Inilah yang disebut reaktivitas.


2. Memahami ref

ref digunakan untuk membuat nilai primitif menjadi reaktif. Nilai seperti string, number, dan boolean biasanya tidak bisa dipantau secara langsung, maka Vue membungkusnya dalam sebuah objek dengan properti .value.

Contoh Dasar

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    Count: {{ count }}
  </button>
</template>

Penjelasan:

  • ref(0) membuat variabel count menjadi objek reaktif.
  • Nilai aktualnya ada di count.value.
  • Di template, Vue otomatis unwrap .value, jadi kita cukup menulis {{ count }}.

3. Memahami reactive

reactive digunakan untuk membuat objek atau array menjadi reaktif. Tidak ada .value karena Vue membuat seluruh properti di dalam objek menjadi “terobservasi”.

Contoh Dasar

<script setup>
import { reactive } from 'vue'

const user = reactive({
  name: 'Budi',
  age: 25
})

function growUp() {
  user.age++
}
</script>

<template>
  <p>{{ user.name }} berusia {{ user.age }}</p>
  <button @click="growUp">Tambah Umur</button>
</template>

Penjelasan:

  • user adalah objek biasa, tapi sekarang semua propertinya (name, age) reaktif.
  • Vue otomatis memantau perubahan sehingga UI langsung ikut berubah.

4. Perbedaan Utama ref vs reactive

Aspekrefreactive
Kegunaan utamaNilai tunggal/primitifObjek dan array
Cara aksesGunakan .value di script, auto unwrap di templateLangsung akses properti
ReaktivitasHanya nilai di .valueDeep reactivity: semua properti dalam objek dipantau
Contoh cocokCounter, boolean flag, string sederhanaForm dengan banyak field, state aplikasi kompleks
KelebihanRingkas, sederhana, bisa juga membungkus objekLebih natural untuk objek, tidak perlu .value
Kekurangan.value terasa aneh bagi pemulaTidak bisa langsung untuk nilai primitif

5. Contoh Praktis ref

a. Counter

<script setup>
import { ref } from 'vue'
const counter = ref(0)
</script>

<template>
  <button @click="counter++">Klik: {{ counter }}</button>
</template>

b. Status Loading

<script setup>
import { ref } from 'vue'
const isLoading = ref(false)
</script>

<template>
  <p>{{ isLoading ? 'Memuat data...' : 'Selesai' }}</p>
  <button @click="isLoading = !isLoading">Toggle</button>
</template>

6. Contoh Praktis reactive

a. Form Input

<script setup>
import { reactive } from 'vue'

const form = reactive({
  username: '',
  email: '',
  password: ''
})
</script>

<template>
  <form>
    <input v-model="form.username" placeholder="Username" />
    <input v-model="form.email" placeholder="Email" />
    <input v-model="form.password" type="password" placeholder="Password" />
  </form>
  <p>{{ form }}</p>
</template>

b. Daftar Todo

<script setup>
import { reactive } from 'vue'

const todos = reactive([
  { id: 1, text: 'Belajar Vue', done: false },
  { id: 2, text: 'Buat proyek kecil', done: true }
])
</script>

<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      <input type="checkbox" v-model="todo.done" /> {{ todo.text }}
    </li>
  </ul>
</template>

7. Studi Kasus: Menggabungkan ref dan reactive

Dalam aplikasi nyata, kita sering memakai keduanya sekaligus.

<script setup>
import { ref, reactive } from 'vue'

const form = reactive({
  username: '',
  email: ''
})

const isSubmitting = ref(false)

function submitForm() {
  isSubmitting.value = true
  setTimeout(() => {
    console.log(form)
    isSubmitting.value = false
  }, 1000)
}
</script>

<template>
  <form @submit.prevent="submitForm">
    <input v-model="form.username" placeholder="Username" />
    <input v-model="form.email" placeholder="Email" />
    <button type="submit" :disabled="isSubmitting">
      {{ isSubmitting ? 'Mengirim...' : 'Kirim' }}
    </button>
  </form>
</template>

Di sini:

  • form dengan reactive karena punya beberapa field.
  • isSubmitting dengan ref karena hanya sebuah boolean sederhana.

8. Best Practices

  • Gunakan ref untuk data primitif, reactive untuk objek/array.
  • Jangan takut menggabungkan keduanya.
  • Jika punya state kompleks dengan banyak nested object, pertimbangkan reactive.
  • Jika ingin memanfaatkan destructuring, hati-hati dengan reactive karena bisa kehilangan reaktivitas. Gunakan toRefs() jika perlu.

Contoh:

import { reactive, toRefs } from 'vue'

const state = reactive({ a: 1, b: 2 })
const { a, b } = toRefs(state) // a dan b tetap reaktif

ref dan reactive adalah dua pilar utama reaktivitas di Vue 3.

  • Gunakan ref untuk nilai sederhana atau tunggal.
  • Gunakan reactive untuk objek atau array dengan banyak properti.
  • Keduanya bisa dipakai bersamaan untuk membangun state aplikasi yang lebih kompleks.

Dengan memahami perbedaan dan penggunaan yang tepat, kita bisa menulis kode yang lebih rapi, konsisten, dan efisien dalam pengembangan aplikasi Vue.