Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Variables reactivas con ref y reactive

14/23
Recursos

Aportes 5

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

La reactividad de VueJS es posible gracias al objeto Proxy en JavaScript.

Proxy nos permite crear una referencia a otro objeto, que se comportará igual que si se tratara del objeto original, pero agregando la capacidad de escuchar cada vez que un valor del objeto cambia para ejecutar algún código.

De hecho, cada cambio que hacemos sobre un objeto Proxy, en realidad se aplica al objeto original, aún así, para JS se sigue tratando de dos objetos distintos, por lo que si aplicamos un cambio al objeto original, el objeto Proxy no se enterará, es decir, el valor si se verá reflejado al accederlo, pero los handlers que escuchan esos cambios no se activarán.

// Ejemplo de proxy
// Se define el objeto original
const obj = {
  counter: 0
};

/*
 Se definen los handlers,
 que escucharán todo lo que suceda con el objeto original.
*/
const handlers = {
  /* 
    Este handler escucha cada vez que
    asignamos un nuevo valor a un atributo del objeto original.
  */
  set(obj, prop, val) {
    /*
      obj: refiere al objeto original
      prop: es el atributo del objeto, por ejemplo: counter
    */
     console.log(`update: ${prop}`);
  }
}

// Creamos un proxy de obj
const proxy = new Proxy(obj, handlers);

// Ejecutamos lo siguiente en la consola
obj.counter 
output: 0

proxy.counter
output: 0

// el handler no se ejecuta
obj.counter++

obj.counter
output: 1

proxy.counter
output: 1

// el handler si se ejecuta
proxy.counter++
output: update counter

obj.counter
output: 2

proxy.counter
output: 2

Es gracias al objeto Proxy, que VueJS puede saber que un valor ha cambiado y así propagar ese cambio a todos los lugares dónde se use ese valor, esto es a lo que conocemos cómo reactividad.

Sin embargo, el objeto Proxy tiene ciertas reglas para funcionar, la principal es que necesita envolver a un objeto, no puede funcionar sobre variables que solo tengan valores de tipo primitivo (números, cadenas de texto, booleanos, etc).

Es por eso que cuándo se trata de valores de tipo primitivo, cómo es el caso de la función ref, siempre tenemos que usar el atributo value para acceder al valor y así mantener la reactividad, pues por detrás estará creando un objeto con la propiedad value, a la cuál le asignará el valor que ref recibe por argumento.

// Podemos imaginar el código de ref más o menos así
function ref(value) {
  return new Proxy({ value }, {
    set(obj, prop, val) {
  	/* Aquí vue escucha cuándo asignamos un nuevo valor */
    }
  });
}

// Uso
const counter = ref(0);
counter.value = 10;
console.log(counter.value); // output 10

Mientras tanto cuándo usamos reactive, el valor que pasamos por argumento ya es un objeto, así que VueJS puede aplicarle todo su sistema de reactividad sin necesidad de hacer nada más.

// Podemos imaginar el código de reactive más o menos así
function ref(value) {
  return new Proxy(value, {
    set(obj, prop, val) {
  	/* Aquí vue escucha cuándo asignamos un nuevo valor */
    }
  });
}

// Uso
const obj = reactive({ counter: 0 });
obj.counter = 10;
console.log(obj.counter); // output 10

Es por esto que en variables creadas con ref necesitamos usar el atributo value, pero en variables creadas con reactive, no es necesario.

Esto también significa que debemos tener cuidado al usar cosas cómo el spread operator (…), ya que estaríamos extrayendo el valor del objeto Proxy, y por lo tanto obtenemos el valor, más no la referencia, y podemos perder la reactividad.

También podemos usar objetos con la función ref, incluso arrays. Pero, para algunos casos, es mejor emplear reactive.

Una de las diferencias entre utilizar ref y reactive es que si asignamos un objeto a ref, podemos sobrescribir el objeto entero asignando un nuevo objeto a su value, mientras que con un objeto creado con reactive no se podría.

const objState = ref({
  isVisible: true,
  name: 'Angel',
});

// reemplazando el objeto completo
objState.value = {
  isVisible: false,
  name: 'Fernando',
};

Este post de StackOverflow explica las diferencias entre Ref y Reactive: Ref vs Reactive

En resumen: Reactive SOLAMENTE funciona con objetos {}.
ref funciona con demás tipos de datos 😃

Tambien con “ref” se puede usar objetos así.

<template>
    <h3>Bienvenidos a vue 3 Composition API</h3>
    <p>{{msg}}</p>
    <p>{{counter.counter}}</p>
</template>
<script>
import { ref } from 'vue';
export default{

    setup(props, ctx){
        console.log(props, ctx)
        const msg = ref("Hello Vue");
        const obj = ref({counter: 0})

        setInterval(()=>{
            obj.value.counter++;
        }, 1000)
        return {
            msg,
            counter: obj.value
        }
    }
}
</script>

No entiendo cual es la ventaja o la diferencia de no utilizarla