Vuex state and getters
Tags: development, vuex, cleancode
Published: 2020-03-10 14:58:20

---
title: Vuex state and getters
published: true
date: 10/03/2020
tags: development,vuex,clean code
description: With vuex is there a reason why it's better to access state directly than via a getter if the getter is just returning the state?
canonical_url: https://blog.ticabri.com/vuex-state-and-getters/
---

_**(edit)** I have evolved my thinking on the subject, which I have expressed in a new article: https://dev.to/enguerran/vuex-state-and-getters-2-2l34_

> With vuex is there a reason why it's better to access state directly than via a getter if the getter is just returning the state?

 ![Vuex state and getters](https://blog.ticabri.com/content/images/2020/03/IMG_20190119_222809.jpg)

Let us first take care to illustrate this issue:

## the store

```
const store = new Vuex.Store({
  state: {
    messages: [
      { from: "Bob", to: "Alice", content: "Hello, Alice!" },
      { from: "Alice", to: "Bob", content: "Hi, Bob!" },
      {
        from: "Bob",
        to: "Alice",
        content:
          `What is the difference between accessing the state directly
          rathen than using a getter?`
      },
      {
        from: "Alice",
        to: "Bob",
        content: `This is your last chance.
          After this, there is no turning back.
          You take the blue pill—the story ends,
          you wake up in your bed and believe whatever you want to believe.
          You take the red pill—you stay in Wonderland,
          and I show you how deep the rabbit hole goes.
          Remember: all I'm offering is the truth. Nothing more.`
      }
    ]
  },
  getters: {
    messages: state => state.messages
  }
});
```
<figcaption>Vuex store</figcaption>
## two very different components

In both components, messages are the responsibility of a Vuex store.

### RedPill: direct access to the state

```
export default {
  name: "HelloWorld",
  computed: {
    messages() {
      return this.$store.state.messages;
    }
  }
};
```
<figcaption>RedPill component</figcaption>

In the component `<RedPill />`, we access the state directly via the store object which is [injected](https://vuex.vuejs.org/guide/state.html#getting-vuex-state-into-vue-components) to all root child components.  
The component retrieves the list of messages and can display their content:

```
<template>
  <div class="hello">
    <h1>Dependant of the state organization</h1>
    <ul v-for="(message, index) in messages" :key="index">
      <li>{{message.from}} to {{message.to}}: {{message.content}}</li>
    </ul>
  </div>
</template>
```
<figcaption>Vue template to display messages</figcaption>
### BluePill: using a getter

```
export default {
  name: "HelloWorld",
  computed: {
    messages() {
      return this.$store.getters.messages;
    }
  }
};
```
<figcaption>BluePill component</figcaption>

In the other component `<BluePill />`, we access the state via a getter which is not complex since it returns directly the object: `const messages = state => state.messages`.

From a component and the application point of view, there is no difference.

## how deep does the rabbit hole go?

The `RedPill` is dependant of the internal state organization. Every time the state is reorganized, the `RedPill` should be updated. The `RedPill` has a big responsibility: to know where it can find the list of messages.

On the other hand, the `BluePill` is independent of the internal organization of the state because it asks the store, whenever it needs it, to return the list of messages. The `BluePill` does not have the responsibility to know where it can find the list of messages.

Let's say that the Vuex store is redesigned to allow organization in modules.

```
const store = new Vuex.Store({
  state: {
    messages: [
      { from: "Bob", to: "Alice", content: "Hello, Alice!" },
      { from: "Alice", to: "Bob", content: "Hi, Bob!" },
      {
        from: "Bob",
        to: "Alice",
        content:
          `What is the difference between accessing the state directly
          rathen than using a getter?`
      },
      {
        from: "Alice",
        to: "Bob",
        content: `This is your last chance.
          After this, there is no turning back.
          You take the blue pill—the story ends,
          you wake up in your bed and believe whatever you want to believe.
          You take the red pill—you stay in Wonderland,
          and I show you how deep the rabbit hole goes.
          Remember: all I'm offering is the truth. Nothing more.`
      }
    ]
  },
  getters: {
    messages: state => state.messages
  }
});
```
<figcaption>Vuex store before refactoring</figcaption>

Now we want to use [Vuex modules](https://vuex.vuejs.org/guide/modules.html):

```
const store = new Vuex.Store({
  modules: {
    messages: {
      state: {
        messages: [
          { from: "Bob", to: "Alice", content: "Hello, Alice!" },
          { from: "Alice", to: "Bob", content: "Hi, Bob!" },
          {
            from: "Bob",
            to: "Alice",
            content: `What is the difference between accessing the state directly
              rathen than using a getter?`
          },
          {
            from: "Alice",
            to: "Bob",
            content: `This is your last chance.
              After this, there is no turning back.
              You take the blue pill—the story ends,
              you wake up in your bed and believe whatever you want to believe.
              You take the red pill—you stay in Wonderland,
              and I show you how deep the rabbit hole goes.
              Remember: all I'm offering is the truth. Nothing more.`
          }
        ]
      },
      getters: {
        messages: state => state.messages
      }
    }
  }
});
```
<figcaption>Vuex store with modules</figcaption>

I have to update the `RedPill` computed data:

```
export default {
  name: "HelloWorld",
  computed: {
    messages() {
      return this.$store.state.messages.messages;
    }
  }
};
```
<figcaption>Tightly coupled to the store</figcaption>

But not the `BluePill`'s one.

```
export default {
  name: "HelloWorld",
  computed: {
    messages() {
      return this.$store.getters.messages;
    }
  }
};
```
<figcaption>Weakly coupled to the store</figcaption>

And that is the same about adding a new feature.

Let's say messages are updated to have a boolean that expresses the need to be displayed or not: `draft: true`.

You just need to update the getter and everything is right:

```
getters: {
  messages: state => state.messages.filter(message => !message.draft)
}
```
<figcaption><a href="https://refactoring.guru/smells/shotgun-surgery">Shotgun surgery</a> avoidance</figcaption>

That is an introduction to [coupling in software development](https://en.wikipedia.org/wiki/Coupling_(computer_programming)).