Episode 7 of 8
Actions
Handle asynchronous operations with actions — dispatch actions that perform async work and then commit mutations to update state.
Actions
Mutations must be synchronous. But real apps need asynchronous operations — API calls, timers, file reads. Actions handle the async logic and then commit mutations when the work is done.
The Flow
Component ──dispatch──→ Action ──(async work)──→ commit ──→ Mutation ──→ State
Defining Actions
// store/store.js
export const store = new Vuex.Store({
state: {
products: [
{ id: 1, name: 'Banana Skin', price: 20 },
{ id: 2, name: 'Shiny Star', price: 40 },
{ id: 3, name: 'Green Shells', price: 60 },
{ id: 4, name: 'Red Shells', price: 80 },
{ id: 5, name: 'Mushroom', price: 15 }
]
},
mutations: {
reducePrice(state, amount) {
state.products.forEach(product => {
product.price -= amount;
});
}
},
actions: {
reducePrice(context, amount) {
// Simulate an async operation (e.g., API call)
setTimeout(() => {
context.commit('reducePrice', amount);
}, 2000);
}
}
});
Actions receive a context object that has the same methods and properties as the store instance. You call context.commit() to trigger a mutation.
Dispatching Actions from Components
<template>
<div>
<button @click="reducePrice">Reduce Prices (2 sec delay)</button>
</div>
</template>
<script>
export default {
methods: {
reducePrice() {
this.$store.dispatch('reducePrice', 4);
}
}
};
</script>
Use this.$store.dispatch('actionName', payload) instead of commit. The action runs, performs async work, and then commits the mutation when ready.
Destructuring Context
actions: {
reducePrice({ commit }, amount) {
setTimeout(() => {
commit('reducePrice', amount);
}, 2000);
}
}
Since you usually only need commit, you can destructure it from the context for cleaner code.
Actions with API Calls
actions: {
async fetchProducts({ commit }) {
const response = await fetch('/api/products');
const data = await response.json();
commit('setProducts', data);
}
}
mutations: {
setProducts(state, products) {
state.products = products;
}
}
commit vs dispatch
| Method | Calls | Use When |
|---|---|---|
this.$store.commit() | A mutation (synchronous) | No async work needed — change state immediately |
this.$store.dispatch() | An action (can be async) | Async work (API calls, timers) before changing state |
Key Takeaways
- Actions handle async logic and then commit mutations to change state
- Dispatch actions with
this.$store.dispatch('actionName', payload) - Actions receive a
contextobject — destructure{ commit }for cleaner code - Use
commitfor synchronous state changes,dispatchfor async workflows