Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js 3 - replace/update reactive object without losing reactivity

I need to update a reactive object with some data after fetching:

  setup(){
    const formData = reactive({})

    onMounted(() => {
      fetchData().then((data) => {
        if (data) {
          formData = data //how can i replace the whole reactive object?
        }
      })
    })
  }

formData = data will not work and also formData = { ...formdata, data }

Is there a better way to do this?

like image 954
claud.io Avatar asked Jan 15 '21 07:01

claud.io


2 Answers

Though Boussadjra Brahim's solution works its not the exact answer to the question.

In the sense that reactive data can not be reassigned with = but their is a way to reassign the reactive data. It is Object.assign.

Therefore this should work

    setup(){
        const formData = reactive({})
    
        onMounted(() => {
          fetchData().then((data) => {
            if (data) {
              Object.assign(formData, data) // equivalent to reassign 
            }
          })
        })
      }

Note: The solution is the Best way when your reactive object empty or always contains same keys; but if e.g formData has key x and data does not have key x then after Object.assign, formData will still have key x, so not strictly not reassigning.

like image 60
ashwin bande Avatar answered Sep 20 '22 17:09

ashwin bande


According to the official docs :

Since Vue's reactivity tracking works over property access, we must always keep the same reference to the reactive object. This means we can't easily "replace" a reactive object because the reactivity connection to the first reference is lost

reactive should define a state with nested fields that could be mutated like :

 setup(){
    const data= reactive({formData :null })

    onMounted(() => {
      fetchData().then((data) => {
        if (data) {
          data.formData = data 
        }
      })
    })

  }

or use ref if you just have one nested field:

  setup(){
    const formData = ref({})

    onMounted(() => {
      fetchData().then((data) => {
        if (data) {
          formData.value = data 
        }
      })
    })

  }
like image 21
Boussadjra Brahim Avatar answered Sep 18 '22 17:09

Boussadjra Brahim