danefondo
danefondo

Reputation: 555

Is it ok to modify Vuex state using only the payload argument of a mutation?

For example, could I iterate over Vuex data in a Vue file and choose the data needing updating, then pass the found data to an action, which commits it and then the mutation only makes the update?

The reason I'm unsure about it is because the typical format of a Vuex mutation contains the parameter for 'state', so I assume it needs to be used, and the only way to do that is either by doing all the looping inside the mutation, or to pass indexes to it to more quickly find the exact fields needing changing.

For who asked, a code example:

someVueFile.vue

computed: {
    ...mapState({
      arrayOfObjects: (state) => state.someVuexStore.arrayOfObjects
    }),
},
methods: {
    myUpdateMethod() {
        let toBePassedForUpdate = null;
        let newFieldState = "oneValue";
        this.arrayOfObjects.forEach((myObject) => {
            if (myObject.someDataField !== "oneValue") {
               toBePassedForUpdate = myObject.someDataField;     
            }
        })

         if (toBePassedForUpdate) {
             let passObject = {
                 updateThis: toBePassedForUpdate,
                 newFieldState: newFieldState
             }

             this.$store.dispatch("updateMyObjectField", passObject)
         }
    }
}

someVuexStore.js

const state = {
  arrayOfObjects: [],
  /* contains some object such as:
    myCoolObject: {
      someDataField: "otherValue"
    }
  */
}

const mutations = {
  updateMyObjectField(state, data) {
    data.updateThis = data.newFieldState;
  }
}

const actions = {
  updateMyObjectField(state, data) {
    state.commit("updateMyObjectField", data);
  }
}

Upvotes: 1

Views: 624

Answers (2)

jcoleau
jcoleau

Reputation: 1200

I would do all of the logic from one action, you can desctructured the context object in the action signature like so :

actions: {
  myAction ({ state, commit, getters, dispacth } ,anyOtherParameter) {
    let myVar = getters.myGetter//use a getter to get your data
    //execute logic
    commit('myCommit', myVar)//commit the change
  }
}

If you need to do the logic in your component you can easily extract the getter and the logic from the action.

Upvotes: 1

Dan
Dan

Reputation: 63059

Yes, it's alright to mutate state passed in through the payload argument rather than state. Vuex doesn't bother to distinguish between the two. In either case, it's the same state, and neither option detracts from the purposes of using mutations.

To feel more sure of that, you can ask what are the purposes of mutations and of enforcing their use. The answer is to keep a centralized, trackable location for concretely defined changes to state.

To illustrate this is a good thing, imagine an app with 1000 components, each one changing state locally, outside of a mutation, and in different ways. This could be a nightmare to debug or comprehend as a 3rd party, because you don't know how or where state changes.

So mutations enforce how and a centralized where. Neither of these are damaged by only using the payload argument in a mutation.

Upvotes: 3

Related Questions