Use Vuex? Try this next!
Tags: vue, es6, beginners
Published: 2020-05-17 23:10:24

*TL;DR, Define your mutation constant together with the function definition, and export both. Allows co-locating the constant with the function so you can `cmd+click` from inside a component, and see the implementation immediately.*

Going by the Vuex [documentation](https://vuex.vuejs.org/guide/mutations.html#using-constants-for-mutation-types), to avoid string literals 

```javascript
this.$store.commit('setLoading', false)
```

is to define your constants in a separate file

**mutation-types.js**

```javascript
export const SET_LOADING = 'setLoading'
```

**MyComponent.vue**

```javascript
import { SET_LOADING } from './mutation-types'
this.$store.commit(SET_LOADING, false);
```

**store.js**

```javascript
const store = new Vuex.Store({
  //...
  mutations: {
    [SET_LOADING] (state, val) {
       state.loading = val;
    }
  }
})
```

Anyone that has ever done this will realize pretty soon that you've lost the ability to `cmd+click` to see the function definition! What you end up at is at

```javascript
export const SET_LOADING = 'setLoading'
```

And then usually selecting `SET_LOADING`, and doing a search in your IDE  to get to your store. 💩

>I've been writing Vue for around 4 years, and React daily for the last 2. If you've ever written action creators, for a React reducer, this should seem pretty familiar.

A better way would be to define your mutation in a separate file

**mutations.js**

```javascript
export const SET_LOADING = 'setLoading'
export const setLoading = (state, val) => {
    state.loading = val;
}
```

*You still have to make sure `setLoading` is the actual function name here, but now it's even easier to spot a typo!*

And in your store you'd import both the constant **and** the function.

**store.js**

```javascript
import {SET_LOADING, setLoading} from './mutations.js'
const store = new Vuex.Store({
  mutations: {
    [SET_LOADING]: setLoading
  }
})
```

Cool! Now you can avoid typing strings, and still `cmd+click` to see the mutation definition!

### 💰Bonus points

Storing the mutations in a separate file also allows breaking up the mutations according to usage, so user mutations can live at: **src/user/state/mutations.js**


### 💰💰Extra bonus points

If you've ever googled *'How to call a mutation from another mutation'*, you'll probably end up creating an *action* to dispatch multiple mutations. While this is perfectly valid, there are some cases where combining mutations makes more sense.

Now that all your mutations are just separate functions, you can just import and call other mutations as you like.

> Combining multiple mutations will make them harder to debug. Consider why you're doing this, and whether you care if they happen in separate steps (use an action), or not (go ahead and combine them).

```javascript

export const MOVE_ITEM = 'moveItem'
function moveItem(state, {oldIndex, newIndex}) {
   const item = state.items[oldIndex]
   deleteItem(state, oldIndex)
   addItem(state, {item, index: newIndex})
   /*
   * This is purely an example, actual implementation 
   * might need you to figure out the modified indexes.
   */
}

function addItem(state, {index, item}) {
   //...
}

function deleteItem(state, {index, item}) {
   //...
}
```

## React ~~vs.~~ ❤️ Vue

React, and Vue might have some fundamental differences, but approaches in one can inspire cleaner code when working with the other.　

I've only recently started doing this, but it's made working with Vuex a better experience personally. If you hate this, and think I'm about to crash, and drown in a pile of spaghetti, please let me know asap!