⭐️ Intro to Vuex and Accessing State
I’m a little scared to admit that I didn’t completely understand why to use Vuex until about a week ago when I watched Adam Jahr’s Vuex tutorial in the Real World Vue course 😮. In this article, I want to give you the information that I wish I would have known about Vuex and State.
🛑 The Problem
As your Vue application grows you’re going to end up with two problems:
- Sending your data all over your app. When you first begin to learn Vue, you discover props and events as a solution for sending around data. But as soon as you have more than 10 components you’ll likely end up in a situation where two components on the opposite side of your app need the same data, and it just doesn’t make sense to send lots of events bubbling up and props sending down. You could use a global event bus, but that pattern has its limitations.
- Data manipulations all over your app. Many years ago Facebook had a problem. They had giant React apps with data that was getting manipulated by many different components. When many different parts of your application are manipulating your data in many different ways (and you have a big app like Facebook) your application can become brittle. This is why Facebook created Flux, the architecture that Vuex is based on.
✅ The Solution
Vuex provides a single place to keep your application data, which from now on we’ll call 🌎 state. All of your components get access to your 🌎 Vuex state, which is reactive. So, if you are accessing some Vuex state from within your components, and that state changes, it will trigger a re-render and the parts of your app using that state will update and re-render as needed.
So that solves problem #1. We no longer need to send data all over our app because it has access to this global state.
To solve problem #2, Vuex introduces Mutations and Actions, which are essentially functions with two different responsibilities.
💥 Mutations are super simple functions which make changes to your state. Mutations are the only way that changes get made to your state. When we call mutations we don’t say that we “call” them; instead we say that we commit them.
📣 Actions are more complex functions that can call one or more mutations. They often perform additional logic, like calculations, conditional logic, or API calls. When we call actions, we say that we “dispatch” them.
Below you can see us dispatching the 📣 fetchTodo action, and that commits the 💥 ‘SET_LOADING_STATUS’ mutation, which changes the state.
In the animation above, the 📣 action is only making one commit, but it goes on to do the following:
As you can see, our 📣 action is in charge of fetching data from an API and calling 💥 mutations that change the 🌏 state.
🌏 Accessing the State
The simplest way you can access Vuex state from a .vue file is shown below (on the left), though you can also place them inside computed properties to simplify how you write them in the template (shown on the right).
Vuex also has a helper called mapState, which makes it easy to map your state to computed properties within your components.
The mapState helper can be simplified further, making it even easier to include our state where needed.
This makes it very convenient to map computed properties to multiple pieces of your state, such as:
computed: mapState(['posts', 'user', 'comments', 'shopping_cart'])
As you can see, mapState is taking up our entire computed property, so you might be wondering how you’d add additional local computed properties here. That’s easy enough to achieve by using the object spread operator.
...mapState(['posts', 'user']) // <-- using object spread operator
⏭ Where to go next?
If you’d like to continue learning Vuex, I highly recommend subscribing to Vue Mastery so you can watch Adam Jahr’s lessons on Intro to Vuex (this is where I got the amazing animation above) and Vuex State + Getters . To get 25% off an annual subscription use the code “VUEMASTERYBLOG25”. Plus $35 of your subscription will go directly to 👐 support the Vue.js project itself.
In the next few weeks we’ll be releasing even more Vuex content.