No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Variables reactivas con ref y reactive

14/23
Recursos

Aportes 10

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

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.

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 😃

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',
};

Como mi novia se molesta un poco porque después de trabajar vengo a programar, encontré una estrategia para que esto no se convierta en un problema…

<template>
    <div>
        <h1>Hola mundo</h1>
        <p>{{text}}</p>
    </div>
</template>


<script>
import { onMounted } from "vue"
import { ref } from "vue";
export default {
    setup() {
        const mensajes = ref(["Te amo mi amor", "Eres el amor de mi vida", "Pamela chu","Colochita mia","Me encanta tu carita mi amor","Te amo mucho","Siempre pienso en ti"])
        const text = ref("Hola vue")
       
        setInterval(() => {
             var x = Math.floor(Math.random() * (mensajes.value.length ));
            text.value = mensajes.value[x]
            
        },1000)
        onMounted(() => {
            console.log("mounted")
            text.value = "New valor, hola vue"
        });

        return {
            text,
        }
    }
}
</script>```

ref()

  • para tipos de datos primitivos y objetos, pero para este último necesita .value para acceder al valor.

reactive()

  • Para arrays y objetos, donde se puede acceder directamente al valor SIN .value

Ejemplo

const personRef = ref({name: 'John'});
const personReactive = reactive({name: 'John'});

personRef.value.name; //John
personReactive.name; //John

Un dato a tener en cuenta al usar Reactive.

Cuando creamos una variable reactiva usando Reactive y un objeto, CADA ATRIBUTO de dicho objeto se comporta como una variable reactiva, no solo el objeto en cuestion. Es decir si tenemos

const obj = reactive({ name: "Francisco", age: 21})

Es lo mismo que:

const obj = reactive( {name: ref("Francisco"), age: ref(21)} )

En cambio, si pasamos a un ref un objeto, solo la referencia al objeto es reactiva, mientras que sus propiedades no lo son.

Una diferencia entre ref y **reactive ** es que la primera se puede emplear para tipos de datos primitivos y referenciados, el reactive solo para referenciados (arrays, objetos), y adem{as en el reactive no necesita el .value para acceder al valor.

ref vs reactive

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

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>

Ref es usado para trabajar con variables primitivas y tambien es posible trabajar con objetos.
.
Reactive es usado para trabajar con objetos y no con primitivos.