Vuex - excessive use of getters in the application. Parsing error


This article will discuss the common mistake most beginners make when developing an application on Vue + Vuex. We will talk about getters and how to use them correctly. We will also look at the helper functions mapState and mapGetters.


Notes before reading: It is recommended to have a basic knowledge of Vue and Vuex.


Chapter 1. What are getters. Example of inappropriate use


Getters are part of the Vuex repository that return the computed data of the current state of the repository to our components.


Consider an example:


const store = new Vuex.Store({
    state: {
        // список книг
        books: [
            { id: 1, title: '...', finished: true },
            { id: 2, title: '...', finished: false }
        ]
    },
    getters: {
        // возвращаем список всех книг
        books: state => state.books
    }
});

This will look like a component with a list of all books:


exportdefault {
    computed: {
        // наш геттер
        books() {
            returnthis.$store.getters.books
        }
    }
}

The example above works, but you should not do that. We overload the application with this approach.


If you need to transfer data directly from the repository to the component without any modifications, getters are not the best solution. Next, I will show how to improve the code and get rid of the inappropriate use of getters.


Chapter 2. Using mapState to retrieve data from the repository


Documentation reads as follows:


When a component has to use many properties or getter storage, it can be tedious to declare all these calculated properties. In such cases, you can use the mapState function , which automatically generates calculated properties.

Let's go back to our component and use mapState instead of the getter:


import { mapState } from'vuex';
exportdefault {
    computed: {
        ...mapState([
            'books'
        ])
    }
}

Getter from storage can be removed, because we no longer need him:


const store = new Vuex.Store({
    state: {
        // список книг
        books: [
            { id: 1, title: '...', finished: true },
            { id: 2, title: '...', finished: false }
        ]
    }
});

Much easier, isn't it? We got rid of unnecessary getters and reduced the amount of code.


Chapter 3. Why do we need getters if there is a mapState


And yet they are needed. Getters are used in cases where you need to display the modified information from the repository (for example, a list of all the books read ).


Let's create a getter to get all the read books from the repository:


const store = new Vuex.Store({
    state: {
        // список книг
        books: [
            { id: 1, title: '...', finished: true },
            { id: 2, title: '...', finished: false }
        ]
    },
    getters: {
        // возвращаем список прочитанных книг
        finishedBooks: state => {
            return state.books.filter(books => books.finished);
        }
    }
});

Now our component will look like this:


import { mapState } from'vuex';
exportdefault {
    computed: {
        // получаем список всех книг
        ...mapState([
            'books'
        ]),
        // получаем список прочитанных книг
        finishedBooks: state => {
            return state.books.filter(books => books.finished);
        }
    }
}

You could stop at that, but there is another useful thing worth knowing. If you need to reuse the same getter in different components, it may not be very convenient to write getters each time in the computed method. MapGetters comes to the rescue .


Let's look at an example:


// не забываем про импортimport { mapState, mapGetters } from'vuex';
exportdefault {
    computed: {
        // получаем список всех книг
        ...mapState([
            'books'
        ]),
        // получаем список геттеров, или в// нашем случае список всех прочитанных книг
        ...mapGetters([
            'finishedBooks'
        ])
    }
}

Improvement on the face: using mapGetters, we have reduced the amount of code.


You can also calculate information from the repository based on some data, for example, get a book by its id or title. This can be achieved by passing the argument to our getter.


const store = new Vuex.Store({
    state: {
        // список книг
        books: [
            { id: 1, title: '...', finished: true },
            { id: 2, title: '...', finished: false }
        ]
    },
    getters: {
        // возвращаем список прочитанных книг
        finishedBooks: state => {
            return state.books.filter(books => books.finished);
        },
        // возвращаем книгу по id
        getBookById: (state) => (id) => {
            return state.books.find(books => books.id === id)
        }
    }
});

import { mapState, mapGetters } from'vuex';
exportdefault {
    computed: {
        ...mapState([
            'books'
        ]),
        ...mapGetters([
            'finishedBooks',
            'getBookById'
        ]),
        getBook() {
            // получаем книгу с id === this.idreturnthis.getBookById(this.id)
        }
    }
}

Fastening material


  • You can use getters in your actions (actions) vuex or directly in the components.
  • The getter results are updated when one of the dependencies changes.
  • Additional arguments can be passed to getters to perform data calculations based on them.
  • Use getters only to calculate non-trivial data that is required in several components; in other cases, use the helper function mapState.

Documentation for getters in Russian


Sample application from the article on codepen


Also popular now: