Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuex 2.0 Dispatch versus Commit

Can someone explain when you would use a dispatch versus a commit?

I understand a commit triggers mutation, and a dispatch triggers an action.

However, isn't a dispatch also a type of action?

like image 503
imchingy Avatar asked Nov 02 '16 21:11

imchingy


People also ask

What is difference between dispatch and commit in Vuex?

Dispatch triggers an action whereas commit triggers a mutation. $dispatch is always used from your methods in routes/components. It sends a message to Vuex store to perform some action. The action can be performed any time after the current tick so that it will not affect the frontend performance.

What is store Dispatch in Vuex?

$dispatch sends a message to your vuex store to do some action. The action may be done anytime after the current tick, so that your frontend performance is not affected. You never commit from any of your components / routes. It is done only from within an action, and only when you have some data to commit.

Does Vuex Dispatch return a Promise?

It's possible for a store. dispatch to trigger multiple action handlers in different modules. In such a case the returned value will be a Promise that resolves when all triggered handlers have been resolved.

Is Vuex dispatch async?

To use async and await with Vuex dispatch, we can add an action method that's an async function.


1 Answers

As you rightly said, $dispatch triggers an action, and commit triggers a mutation. Here is how you can use these concepts:

You always use $dispatch from your methods in routes / components. $dispatch sends a message to your vuex store to do some action. The action may be done anytime after the current tick, so that your frontend performance is not affected.

You never commit from any of your components / routes. It is done only from within an action, and only when you have some data to commit. Reason: commit is synchronous and may freeze your frontend till it is done.

Let's consider this case: If you have to fetch some json data from server. In this case, you need to do this asynchronously so that your user interface is not unresponsive / frozen for a while. So, you simply $dispatch an action and expect it to be done later. Your action takes up this task, loads data from server and updates your state later.

If you need to know when an action is finished, so that you can display an ajax spinner till then, you may return a Promise as explained below (example: load current user):

Here is how you define the "loadCurrentUser" action:

actions: {     loadCurrentUser(context) {         // Return a promise so that calling method may show an AJAX spinner gif till this is done         return new Promise((resolve, reject) => {             // Load data from server             // Note: you cannot commit here, the data is not available yet             this.$http.get("/api/current-user").then(response => {                 // The data is available now. Finally we can commit something                 context.commit("saveCurrentUser", response.body)  // ref: vue-resource docs                 // Now resolve the promise                 resolve()             }, response => {                 // error in loading data                 reject()             })         })     },     // More actions } 

In your mutations handler, you do all the commits originating from actions. Here is how you define the "saveCurrentUser" commit:

mutations: {     saveCurrentUser(state, data) {         Vue.set(state, "currentUser", data)     },     // More commit-handlers (mutations) } 

In your component, when it is created or mounted, you just call the action as shown below:

mounted: function() {     // This component just got created. Lets fetch some data here using an action     // TODO: show ajax spinner before dispatching this action     this.$store.dispatch("loadCurrentUser").then(response => {         console.log("Got some data, now lets show something in this component")         // TODO: stop the ajax spinner, loading is done at this point.     }, error => {         console.error("Got nothing from server. Prompt user to check internet connection and try again")     }) } 

Returning a Promise as shown above is entirely optional and also a design decision not preferred by everyone. For a detailed discussion on whether to return a Promise or not, you may read the comments under this answer: https://stackoverflow.com/a/40167499/654825

like image 66
Mani Avatar answered Oct 22 '22 14:10

Mani