Home > Net >  reactivity disappears after the object was in the array
reactivity disappears after the object was in the array

Time:02-10

Why, after passing through the reactive array, did the element's reactive property turn into a non-reactive one? Can you explain please.

<script setup lang="ts">
    import { ref, Ref } from 'vue'
    
    interface Obj { 
      a: number;
      r: Ref<{s:string}>;
    }
    const obj: Obj = { a: 1, r: ref<string>({s:"one"}) }; //create an instance
    const valBeforeArr=obj.r.value  //the variable is displayed as it should be
    //put an instance in a reactive array, and get from it    
    const arr = ref<Obj[]>([]);
    arr.value.push(obj)  
    const valAfterArrRef=arr.value[0].r.value //reference value missing
    const valAfterArrNonRef=arr.value[0].r //and the original value is displayed normally
    </script>
    
    <template>
      <h2>valBeforeArr: {{ valBeforeArr }}</h2>
      <h2>valAfterArrRef: {{ valAfterArrRef ?? 'underfined' }}</h2>
      <h2>valAfterArrNonRef: {{ valAfterArrNonRef ?? 'underfined' }}</h2>
    </template>

playground

As explained to me Estus Flask, reactivity has not disappeared. You can verify this with the following code:

<template>
  <h2>valBeforeArr: {{ valBeforeArr }}</h2>
  <h2>valAfterArrRef: {{ valAfterArrRef ?? 'underfined' }}</h2>
  <h2>valAfterArrNonRef: {{ valAfterArrNonRef ?? 'underfined' }}</h2>
  <button @click="obj.r.value.s='seven'">updateBeforeArr</button>
  <button @click="arr[0].r.s='five'">updateAfterArr</button>
</template>

But in one case you have to access using ".value", and in the other, without it. This is inconvenient, given that the object, in accordance with the business logic, can either pass through the array or not. How to access a property universally?

CodePudding user response:

The documentation explains this:

When a ref is accessed or mutated as a property of a reactive object, it automatically unwraps to the inner value so it behaves like a normal property

<...>

Ref unwrapping only happens when nested inside a reactive Object. There is no unwrapping performed when the ref is accessed from an Array or a native collection type like Map

Since ref is deeply reactive, arr.value elements are reactive objects, and refs in obj properties are unwrapped when it's added to the array and becomes reactive.

shallowRef can be used in order to avoid unwrapping in nested refs.

  • Related