--- title: Prefer ref() Over reactive() for Consistency impact: MEDIUM impactDescription: Using ref() as default avoids reactive() gotchas and provides consistent patterns type: efficiency tags: [vue3, reactivity, ref, reactive, composition-api, best-practice] --- # Prefer ref() Over reactive() for Consistency **Impact: MEDIUM** - The Vue documentation recommends using `ref()` as the primary API for declaring reactive state. This avoids several `reactive()` gotchas and provides a consistent pattern across your codebase. While both `ref()` and `reactive()` create reactive state, `reactive()` has several limitations: it only works with objects (not primitives), cannot be reassigned, and loses reactivity when destructured. Using `ref()` consistently means one pattern to remember. ## Task Checklist - [ ] Use `ref()` as the default for all reactive state - [ ] Only use `reactive()` when you have a specific reason (e.g., group of related state) - [ ] Be consistent within a codebase - pick one approach and stick with it - [ ] Remember: `.value` is the price for avoiding `reactive()` gotchas **Incorrect:** ```javascript import { reactive } from 'vue'; // reactive() has multiple gotchas: // 1. Cannot use with primitives const count = reactive(0); // Won't work - not reactive // 2. Cannot reassign the entire object let state = reactive({ items: [] }); state = reactive({ items: [1, 2, 3] }); // Loses reactivity! // 3. Destructuring breaks reactivity const { items } = state; // items is not reactive // 4. Passing to functions can lose reactivity someFunction(state.items); // May lose reactivity depending on usage ``` **Correct:** ```javascript import { ref } from 'vue'; // ref() works universally: // 1. Works with primitives const count = ref(0); count.value++; // Works! // 2. Can reassign the entire object const state = ref({ items: [] }); state.value = { items: [1, 2, 3] }; // Reactivity preserved! // 3. No destructuring issues (you work with .value) const items = state.value.items; // If you need just the value // 4. Passing refs is explicit someFunction(state); // Pass the ref someFunction(state.value); // Or pass the value explicitly ``` ```javascript // When reactive() makes sense: grouping related state import { reactive, toRefs } from 'vue'; // Acceptable use case: form state with many related fields const form = reactive({ username: '', email: '', password: '', confirmPassword: '', }); // But always use toRefs() if you need to destructure const { username, email } = toRefs(form); ``` ## Reference - [Vue.js Reactivity Fundamentals](https://vuejs.org/guide/essentials/reactivity-fundamentals.html) - [Vue.js Composition API FAQ](https://vuejs.org/guide/extras/composition-api-faq.html)