Skip to content
Advertisement

How to update reactive object without losing reactivity (vue3 compositionAPI)

I tryed to update a reactive object , but reactivity is lost.

How to solve this problem?

const obj = reactive({ id:0 , name: "Tom" })


const updateObj = { id:1 , name: "Bob" }

Object.keys(updateObj).forEach(key => {
   obj[key] = updateObj[key]
 })


console.log( isRef( obj.id ) )  // => false

Advertisement

Answer

Actually your example should work, when it comes to reactivity. Instead of iterating through the keys, it might be a better idea to simply use Object.assign(obj, updateObj), but your approach should work as well.

But, it seems you have a slight misconception about reactivity and the isRef function: isRef does not check if the given argument is reactive, but specifically if it is a ref object (see this section in the Vue docs). There is also a function called isReactive that can check specifically, if an object is a reactive object (see here). Note, that this does also not return true for the property of a reactive object.

I’ve created a small example, that should illustrate the difference between the two methods. It also shows, that reactivity works, even if the isRef and isReactive functions both return false:

<script setup>
import { computed, reactive, ref, isReactive, isRef } from 'vue';
  
const obj = reactive({ id: 0 , name: "Tom" })
const realRef = ref('foo')

const isRefOrReactive = computed(() => ({
  objRef: isRef(obj),
  objReactive: isReactive(obj),
  objIdRef: isRef(obj.id),
  objIdReactive: isReactive(obj.id),
  refRef: isRef(realRef),
  refReactive: isReactive(realRef)
}))

const updateObject = () => {
  const updateObj = { id: 1 , name: "Bob" }
  Object.keys(updateObj).forEach(key => {
    obj[key] = updateObj[key]
  })
  // Object.assign(obj, updatedObj)
}
</script>

<template>
  <pre>{{ obj }}</pre>
  <pre>{{ obj.name }}</pre>
  <pre>{{ isRefOrReactive }}</pre>
  <button @click="updateObject">
    Swap data
  </button>
</template>
Advertisement