What are mapState and mapActions in Vuex?
In Vue, the component’s local state, actions, and other properties are usually defined separately in data
, methods
, computed
, etc. But when we use Vuex, which is a centralized state management tool, we have to pull in state and actions from this central store. This is where mapState
and mapActions
come in handy.
mapState:
mapState
is a helper function from Vuex that maps the component’s computed properties to the state of the store. Instead of accessing the state directly with this.$store.state.someState
, mapState
provides a shortcut.
Simple Example:
Imagine you have a centralized store that keeps the count of apples:
state: {
apples: 5
}
Without mapState
, you’d access it like this:
computed: {
applesCount() {
return this.$store.state.apples;
}
}
With mapState
, this becomes:
computed: {
...mapState(['apples'])
}
Now, you can just use this.apples
directly in your template or methods to get the value from the store.
Why convert mapState
to a computed property?
Computed properties are reactive in Vue. This means whenever the state (apples
in our example) changes in the Vuex store, the computed property (this.apples
) will automatically update and re-render in the component, ensuring the UI always reflects the latest state.
mapActions:
mapActions
maps the component’s methods to store actions. Actions in Vuex are where we typically put asynchronous operations or any logic before committing a mutation.
Simple Example:
Suppose you have an action that adds more apples:
actions: {
addMoreApples(context, numberToAdd) {
// logic here...
context.commit('ADD_APPLES', numberToAdd);
}
}
Without mapActions
, you’d dispatch this action like:
methods: {
addApples(num) {
this.$store.dispatch('addMoreApples', num);
}
}
With mapActions
, this simplifies to:
methods: {
...mapActions(['addMoreApples'])
}
You can then call this.addMoreApples(num)
directly.
Why convert mapActions
to a method?
Actions are functions that a component might call in response to user input or other events. By mapping them to the component’s methods, they can be easily called from within the component, just like any other method you’d define.
In summary, mapState
and mapActions
are helper functions that offer a concise way to integrate Vuex store’s state and actions into Vue components. They make the code cleaner, more readable, and leverage Vue’s reactivity system effectively.
An Auth example Using Vuex Store.
state: {
// Initialize isLoggedIn from localStorage to persist login status across page refreshes
isLoggedIn: !!localStorage.getItem('token')
},
// Mutations are functions that directly mutate the state.
// Each mutation handler gets the entire state tree as the first argument.
mutations: {
// Mutation to set isLoggedIn to true
LOGIN(state) {
state.isLoggedIn = true
},
// Mutation to set isLoggedIn to false
LOGOUT(state) {
state.isLoggedIn = false
}
},
// Actions are functions that cause side effects and can involve
// asynchronous operations. Actions can also commit mutations.
actions: {
// Login action that commits LOGIN mutation
login({ commit }) {
// login logic here, then:
commit('LOGIN')
},
// Logout action that commits LOGOUT mutation and dispatches navigateToLogin action
logout({ commit, dispatch }) {
commit('LOGOUT');
dispatch('navigateToLogin');
},
// Action to navigate to login route using Vue Router
navigateToLogin() {
router.push({ name: 'Login' });
}
}
})
Let’s simplify this with an analogy:
Imagine the state as a toy box. Inside the toy box, there’s a switch named isLoggedIn
which tells if a toy is ON (true) or OFF (false).
Mutations are like instructions that can either turn this toy ON or OFF. They can’t decide when or why to turn the toy on or off; they just do it when told.
Actions are like little kids. When they decide they want to play (like when someone tries to log in or log out), they follow the mutations’ instructions to turn the toy ON or OFF. Sometimes, after turning the toy off, they might also decide to move to another game (like navigating to the login page).
So, when we say commit('LOGIN')
inside an action, it’s like the kid deciding to play and turning the toy ON by following the LOGIN
instruction. “committing” in this context means to “run” or “execute” the mutation.
So I have a question. What kind of code would you have in a component like Navbar.vue since the above code is for a Vuex central store or a management store for our login, logout, and Navigate to the Login page?
Please comment below…
Pingback: The Vue 3 Computed Properties Guide - Webdev Trainee