Search code examples
javascriptvue.jsvuexmutation

Vue3/Vuex - Component not reflecting state change when using destructuring assignment


I am using Vue 3 with Vuex. I am unable to get Vue to react to a change in state when mutating the state via destructuring assignment. Though, I am able to get Vue to react when I change state via a mutation that only reassigns a single value.

Am I doing something incorrectly?

The following code works

I have a component that pulls in a Vuex getter in setup():

const someValue = computed(() => store.getters['app/getSomeValue'])

The code below dispatches the action that mutates this value and will react just fine:

store.dispatch('app/setSomeValue', newValue)

The mutation:

setSomeValue(state, value) {
  state.someValue = value
},

The following code does not work

What if I wanted to alter multiple properties of a module's state without having to rely on multiple mutations? I'd use object destructuring. The following code, when logged, shows that a state change does happen, but neither the component that uses it nor Vuex devtools reflects a change.

  1. The action being dispatched:
store.dispatch('app/setSomeValue', { someValue: newValue })
  1. The mutation using destructuring:
setState(state, payload) {
 state = { ...state, ...payload }
}

Now, I shouldn't even have to change the getter. Though using this method, Vue doesn't pick up on a change. If I log state after I use destructuring, it shows someValue as being updated. What gives?


Solution

  • Reassigning the entire state object must be breaking reactivity or otherwise causing Vuex to lose track of state changes somehow.

    Use Object.assign to copy the key-values from your payload to your store's state while maintaining the same original state object in memory.

    setState(state, payload) {
      Object.assign(state, payload)
    }