Vuex State and Getters (2)
Tags: développement
Published: 2020-04-27 16:43:15

---
title: Vuex State and Getters (2)
published: true
date: 2020-04-27 16:30:00 UTC
tags: développement
canonical_url: https://blog.ticabri.com/vue-state-and-getters-2/
---

 ![Vuex State and Getters (2)](https://blog.ticabri.com/content/images/2020/04/IMG_20190119_223007.jpg)

To be honest, I wasn't sure what I was writing when I wrote [the previous article about Vuex State and Getters](https://dev.to/enguerran/vuex-state-and-getters-1cep). And the more I use Vuex, the more I question this "everything in Getters" proposition. In the end, writing this article allowed me to review the situation.

I know why something did not smell right to me.

## The case of the Vuejs components

Several data are accesible within a component, they can come from `props`, be defined in `data` or be calcultated in `computed`.

When we use them in the teplate, we don't ask ourselves the question of their origins, they are all accessible through the `this` interface.

```
Vue.component("ButtonCounter", {
  props: {
    name: {
      type: String,
      default: () => "John Doe"
    }
  },
  data: function() {
    return {
      count: 0
    };
  },
  computed: {
    times: function() {
      return this.count === 1 ? "time" : "times";
    }
  },
  template: `
  <button v-on:click="count++">
    Hi {{name}}, you clicked me {{ count }} {{times}}.
  </button>`
});
```
<figcaption>Vuejs props, data and computed properties</figcaption>

([Codesandbox Vuejs demo](https://codesandbox.io/s/state-and-getters-vuejs-p4b04))

## The case of React components

There are two interfaces: `this.state` and `this.props`. The first handles internal data of the component. The second handles external data of the component whether it comes from the calling component or the state manager.

```
class ButtonCounter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    const { count } = this.state;
    const { username } = this.props;
    const times = count === 1 ? "time" : "times";
    return (
      <button
        onClick={() => {
          this.setState({ count: count + 1 });
        }}
      >
        Hi {username}, you clicked me {count} {times}.
      </button>
    );
  }
}
```
<figcaption>React props and state</figcaption>

([Codesandbox Reactjs demo](https://codesandbox.io/s/state-and-getters-reactjs-vczct))

## The case of Vuex

Whether the data is directly provided by the state of the store, or the data is derived, we don't have the same interface: `this.state` vs `this.getters`. And the consumer of the data has to be aware of the internal organization of the store, which is a bit disturbing.

```
const initialState = {
  todos: [
    { id: 1, text: 'Learn about State', done: true },
    { id: 2, text: 'Learn about Getters', done: false }
  ]
};

function doneTodos(state) {
  return state.todos.filter(todo => todo.done)
}

const store = new Vuex.Store({
  state: initialState,
  getters: {
    doneTodos: doneTodos
  }
})

```
<figcaption>Vuex state and getters</figcaption>

To access the `todos`, components can add a `computed` properties:

```
Vue.component("TodoList", {
  computed: {
    todos: function() {
      return this.$store.state.todos
    },
    doneTodos: function() {
      return this.$store.getters.doneTodos
    }
  },
  template: `
  <ul>
    <li v-for="todo in todos" :key="todo.text">
      {{ todo.text }}
    </li>
  </ul>`
});
```
<figcaption>Usage with Vuejs</figcaption>
## The case of Redux

Getters are referred to as _Selectors_ and handle providing [derived data](https://redux.js.org/recipes/computing-derived-data). In a redux vanilla framework, we will implement a function well-named `mapStateToProps` (transforming a data of the global state into a component's `props` property).

```
const initialState = {
  todos: [
    { id: 1, text: 'Learn about State', done: true },
    { id: 2, text: 'Learn about Selectors', done: false }
  ]
};

function doneTodos(state) {
  return state.todos.filter(todo => todo.done)
}

const store = createStore(function(state, action) {
  if (typeof state === 'undefined') {
    return initialState
  }
    
  return state;
});
```
<figcaption>Redux state and selectors</figcaption>

This creates [container components](https://redux.js.org/basics/example#container-components) (connected to the state manager).

```
class TodoList extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    const { todos, doneTodos } = this.pros;
    return (
      <ul>
        {todos.map(todo => (
          <li>{todo.text}</li>
        ))}
      </ul>
    );
  }
}

const mapStateToProps = state => {
  return {
    todos: state.todos,
    doneTodos: doneTodos(state)
  }
};

const TodoListContainer = connect(mapStateToProps)(TodoList)
```
<figcaption>Usage with Reactjs</figcaption>
## Conclusion

React and Redux don't do something special for computed properties or getters, they are only functions that take a raw data as a parameter and return a computed data.

Vuejs and Vuex treat computed properties and getters in a special way that force developers to adapt their code to the framework (in order to be reactive):

1. The Vuejs component that consumes a Vuex data must know how the state is organised;
2. Developers need to know the correct interface to access the state data regarding if they are raw or computed data.