[Medium] ref vs reactive
1. What are ref and reactive?
¿Qué son ref y reactive?
ref y reactive son las dos APIs principales en Vue 3 Composition API para crear datos reactivos.
ref
Definición: ref se usa para crear un valor de tipo primitivo o una referencia a objeto reactiva.
Clic para ver ejemplo básico de ref
<script setup>
import { ref } from 'vue';
// Tipos primitivos
const count = ref(0);
const message = ref('Hello');
const isActive = ref(true);
// Objetos (también se puede usar ref)
const user = ref({ name: 'John', age: 30 });
// Se necesita usar .value para acceder
console.log(count.value); // 0
count.value++; // Modificar valor
</script>
reactive
Definición: reactive se usa para crear un objeto reactivo (no se puede usar directamente con tipos primitivos).
Clic para ver ejemplo básico de reactive
<script setup>
import { reactive } from 'vue';
// Solo se puede usar con objetos
const state = reactive({
count: 0,
message: 'Hello',
user: { name: 'John', age: 30 },
});
// Acceso directo a propiedades, sin necesidad de .value
console.log(state.count); // 0
state.count++; // Modificar valor
</script>
2. ref vs reactive: Key Differences
Principales diferencias entre ref y reactive
1. Tipos aplicables
ref: Se puede usar con cualquier tipo
const count = ref(0); // ✅ Número
const message = ref('Hello'); // ✅ Cadena
const isActive = ref(true); // ✅ Booleano
const user = ref({ name: 'John' }); // ✅ Objeto
const items = ref([1, 2, 3]); // ✅ Arreglo
reactive: Solo se puede usar con objetos
const state = reactive({ count: 0 }); // ✅ Objeto
const state = reactive([1, 2, 3]); // ✅ Arreglo (también es un objeto)
const count = reactive(0); // ❌ Error: no se puede con tipos primitivos
const message = reactive('Hello'); // ❌ Error: no se puede con tipos primitivos
2. Forma de acceso
ref: Se necesita usar .value para acceder
Clic para ver ejemplo de acceso con ref
<script setup>
import { ref } from 'vue';
const count = ref(0);
// En JavaScript se necesita usar .value
console.log(count.value); // 0
count.value = 10;
// En la plantilla se desenvuelve automáticamente, no necesita .value
</script>
<template>
<div>{{ count }}</div>
<!-- Desenvuelve automáticamente, no necesita .value -->
</template>
reactive: Acceso directo a propiedades
Clic para ver ejemplo de acceso con reactive
<script setup>
import { reactive } from 'vue';
const state = reactive({ count: 0 });
// Acceso directo a propiedades
console.log(state.count); // 0
state.count = 10;
</script>
<template>
<div>{{ state.count }}</div>
</template>
3. Reasignación
ref: Se puede reasignar
const user = ref({ name: 'John' });
user.value = { name: 'Jane' }; // ✅ Se puede reasignar
reactive: No se puede reasignar (pierde la reactividad)
let state = reactive({ count: 0 });
state = { count: 10 }; // ❌ Pierde la reactividad, no se actualiza la vista
4. Desestructuración
ref: Mantiene la reactividad después de desestructurar
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value; // Desestructura valores primitivos, pierde reactividad
// Pero se puede desestructurar el ref en sí
const nameRef = ref('John');
const ageRef = ref(30);
reactive: Pierde la reactividad después de desestructurar
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state; // ❌ Pierde reactividad
// Se necesita usar toRefs para mantener la reactividad
import { toRefs } from 'vue';
const { count, message } = toRefs(state); // ✅ Mantiene reactividad
3. When to Use ref vs reactive?
¿Cuándo usar ref? ¿Cuándo usar reactive?
Situaciones para usar ref
-
Valores de tipo primitivo
const count = ref(0);
const message = ref('Hello'); -
Objetos que necesitan reasignación
const user = ref({ name: 'John' });
user.value = { name: 'Jane' }; // Se puede reasignar -
Template Refs
<template>
<div ref="container"></div>
</template>
<script setup>
const container = ref(null);
</script> -
Cuando se necesita desestructuración
const state = ref({ count: 0, message: 'Hello' });
// La desestructuración de valores primitivos no tiene problema
Situaciones para usar reactive
-
Estado de objeto complejo
const formState = reactive({
username: '',
password: '',
errors: {},
}); -
Estado que no necesita reasignación
const config = reactive({
apiUrl: 'https://api.example.com',
timeout: 5000,
}); -
Múltiples propiedades relacionadas organizadas juntas
const userState = reactive({
user: null,
loading: false,
error: null,
});
4. Common Interview Questions
Preguntas comunes de entrevista
Pregunta 1: Diferencias básicas
Explica las diferencias y resultados de salida del siguiente código.
// Caso 1: Usando ref
const count1 = ref(0);
count1.value = 10;
console.log(count1.value); // ?
// Caso 2: Usando reactive
const state = reactive({ count: 0 });
state.count = 10;
console.log(state.count); // ?
// Caso 3: Reasignación de reactive
let state2 = reactive({ count: 0 });
state2 = { count: 10 };
console.log(state2.count); // ?
Clic para ver la respuesta
// Caso 1: Usando ref
const count1 = ref(0);
count1.value = 10;
console.log(count1.value); // 10 ✅
// Caso 2: Usando reactive
const state = reactive({ count: 0 });
state.count = 10;
console.log(state.count); // 10 ✅
// Caso 3: Reasignación de reactive
let state2 = reactive({ count: 0 });
state2 = { count: 10 }; // ❌ Pierde reactividad
console.log(state2.count); // 10 (el valor es correcto, pero pierde reactividad)
// Las modificaciones posteriores de state2.count no activarán actualización de la vista
Diferencias clave:
refnecesita.valuepara accederreactiveaccede directamente a las propiedadesreactiveno se puede reasignar, de lo contrario pierde la reactividad
Pregunta 2: Problema de desestructuración
Explica el problema del siguiente código y proporciona una solución.
// Caso 1: Desestructuración de ref
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value;
name = 'Jane'; // ?
// Caso 2: Desestructuración de reactive
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state;
count = 10; // ?
Clic para ver la respuesta
Caso 1: Desestructuración de ref
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value;
name = 'Jane'; // ❌ No actualiza user.value.name
// Forma correcta: modificar el valor de ref
user.value.name = 'Jane'; // ✅
// O reasignar
user.value = { name: 'Jane', age: 30 }; // ✅
Caso 2: Desestructuración de reactive
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state;
count = 10; // ❌ Pierde reactividad, no activa actualización
// Forma correcta 1: modificar la propiedad directamente
state.count = 10; // ✅
// Forma correcta 2: usar toRefs para mantener reactividad
import { toRefs } from 'vue';
const { count, message } = toRefs(state);
count.value = 10; // ✅ Ahora es ref, necesita usar .value
Resumen:
- Desestructurar valores primitivos pierde la reactividad
- La desestructuración de
reactivenecesita usartoRefspara mantener la reactividad - La desestructuración de propiedades de objeto de
reftambién pierde reactividad, se debe modificar.valuedirectamente
Pregunta 3: ¿Elegir ref o reactive?
Indica si se debe usar ref o reactive en los siguientes escenarios.
// Escenario 1: Contador
const count = ?;
// Escenario 2: Estado de formulario
const form = ?;
// Escenario 3: Datos de usuario (puede necesitar reasignación)
const user = ?;
// Escenario 4: Referencia de plantilla
const inputRef = ?;
Clic para ver la respuesta
// Escenario 1: Contador (tipo primitivo)
const count = ref(0); // ✅ ref
// Escenario 2: Estado de formulario (objeto complejo, no necesita reasignación)
const form = reactive({
username: '',
password: '',
errors: {},
}); // ✅ reactive
// Escenario 3: Datos de usuario (puede necesitar reasignación)
const user = ref({ name: 'John', age: 30 }); // ✅ ref (se puede reasignar)
// Escenario 4: Referencia de plantilla
const inputRef = ref(null); // ✅ ref (las referencias de plantilla deben usar ref)
Principios de selección:
- Tipo primitivo →
ref - Objeto que necesita reasignación →
ref - Referencia de plantilla →
ref - Estado de objeto complejo, sin necesidad de reasignación →
reactive
5. Best Practices
Mejores prácticas
Recomendaciones
// 1. Tipos primitivos usan ref
const count = ref(0);
const message = ref('Hello');
// 2. Estados complejos usan reactive
const formState = reactive({
username: '',
password: '',
errors: {},
});
// 3. Necesidad de reasignación usa ref
const user = ref({ name: 'John' });
user.value = { name: 'Jane' }; // ✅
// 4. Desestructuración de reactive usa toRefs
import { toRefs } from 'vue';
const { count, message } = toRefs(state);
// 5. Unificar estilo: el equipo puede elegir usar principalmente ref o reactive
Prácticas a evitar
// 1. No usar reactive para crear tipos primitivos
const count = reactive(0); // ❌ Error
// 2. No reasignar reactive
let state = reactive({ count: 0 });
state = { count: 10 }; // ❌ Pierde reactividad
// 3. No desestructurar reactive directamente
const { count } = reactive({ count: 0 }); // ❌ Pierde reactividad
// 4. No olvidar .value en la plantilla (para ref)
// En la plantilla no necesita .value, pero en JavaScript sí
6. Interview Summary
Resumen de entrevista
Puntos clave para recordar
ref:
- Aplicable a cualquier tipo
- Se necesita
.valuepara acceder - Se puede reasignar
- Se desenvuelve automáticamente en la plantilla
reactive:
- Solo para objetos
- Acceso directo a propiedades
- No se puede reasignar
- La desestructuración necesita
toRefs
Principios de selección:
- Tipo primitivo →
ref - Necesita reasignación →
ref - Estado de objeto complejo →
reactive
Ejemplo de respuesta para entrevista
Q: ¿Cuál es la diferencia entre ref y reactive?
"ref y reactive son APIs de Vue 3 para crear datos reactivos. Las principales diferencias incluyen: 1) Tipos aplicables: ref se puede usar con cualquier tipo, reactive solo con objetos; 2) Forma de acceso: ref necesita .value para acceder, reactive accede directamente a las propiedades; 3) Reasignación: ref se puede reasignar, reactive no se puede reasignar o pierde la reactividad; 4) Desestructuración: la desestructuración de reactive necesita usar toRefs para mantener la reactividad. En general, los tipos primitivos y los objetos que necesitan reasignación usan ref, y los estados de objetos complejos usan reactive."
Q: ¿Cuándo se debe usar ref? ¿Cuándo reactive?
"Usar ref en: 1) valores de tipo primitivo (números, cadenas, booleanos); 2) objetos que necesitan reasignación; 3) referencias de plantilla. Usar reactive en: 1) estados de objetos complejos, organizando múltiples propiedades relacionadas juntas; 2) estados que no necesitan reasignación. En la práctica, muchos equipos unifican el uso de ref porque es más flexible y tiene un rango de aplicación más amplio."