Как и когда правильно использовать actions Vuex для API-запросов?

После прочтение нескольких статей на тему Vuex и API calls пришел к выводу, что запросы к API надо делать внутри actions Vuex (якобы это best practices). Однако, я совершенно не понимаю, всегда ли это необходимо. Для наглядности приведу пример.

Задача: получить и отображать в компоненте список пользователей.

Создаем простое хранилище Vuex:

export default new Vuex.Store({
    state: {
        users: []
    },

    getters: {
        getUsers(state) {
            return state.users;
        }
    },
    actions: {
        loadUsers({ commit }) {
            getUsersAPICall().then(function(response) {
                commit("saveUsers", response['data']);
            })
        },
    },
    mutations: {
        saveUsers(state, users) {
            state.users = users;
        },
    }
})

И компонент, который отображает список пользователей:

export default {
    name: "Items",
    computed: {
        users() {
            return this.$store.getters['getUsers'];
        }
    },
    created() {
        this.$store.dispatch('loadUsers');
    }
}

В таком виде все работает и все хорошо. Но теперь мне надо реализовать возможность добавления пользователей.

По идее в actions добавляем метод addUser:

actions: {
        .....
        addUser({ commit }) {
            addUserAPICall().then(function(response) {
                // TODO
            })
        },
    },

Подскажите, что делать дальше, после того как запрос ушел на сервер и мы получили ответ, что пользователь добавлен?

Создать и вызвать мутацию addUser для добавления нового пользователя в state? Но, по-моему, это неправильно: ведь параллельно кто-то может тоже добавлять пользователей на сервере, а мы об этом не узнаем. Т.е. по идее нужно снова вызвать action loadUsers(), но в чем тогда смысл нашего state? В данном случае он выглядит какой-то прослойкой между сервером и нашим компонентом, при этом не являясь тем самым "источником истины", потому что при любом действии все равно необходимо загружать данные с сервера.
  • Вопрос задан
  • 2160 просмотров
Решения вопроса 2
Athanor
@Athanor
Лайк + Решение: не жмись, нажми
пришел к выводу, что запросы к API надо делать внутри actions Vuex (якобы это best practices). Однако, я совершенно не понимаю, всегда ли это необходимо

Выносить общение с api слоем в vuex оправдано, когда данные, которые оттуда приходят вы храните в vuex.

При этом, конечно же, лучше при мутации чего-то на сервере обновлять этот список с сервера, а не пробовать повторить эту мутацию локально.

Что касается вашего вопроса про то, что vuex выглядит прослойкой: у него изначально другое предназначение, он не обязан полностью содержать актуальные данные из бд, это слой с данными для приложения и нужен он для того, чтоб все общие данные лежали в одном месте.

PS
1. добавьте в ваши actions, использующие вызовы API return, иначе при вызове в компоненте они будут возвращать не тот промис, который вы от них ожидаете.
2. Использование хэлперов mapActions, mapGetters.. позволит сделать общение с vuex в компонентах гораздо симпатичней
Ответ написан
Kozack
@Kozack Куратор тега Vue.js
Thinking about a11y
запросы к API надо делать внутри actions Vuex (якобы это best practices). Однако, я совершенно не понимаю, всегда ли это необходимо


state нужен в тех случаях, когда доступ к списку пользователей вам нужен не в одном компоненте, а как минимум в двух. В таких случаях без него никак.

Если вы уверены, что список пользователей вам нужен только в одном компоненте — тогда все данные нужно хранить именно в нем.

Важно понимать разницу:
  • Данные в Vuex "существуют" всегда и всегда занимают часть памяти на клиенте.
  • Данные в компоненте "существуют" только когда существует компонент. И будут удалены если удалится компонент.


Если ваше приложение завязано на списке пользователей, и несколько компонентов используют эти данные, то без Vuex вам будет сложно.

В то же время, если список пользователей вам нужен только для какого-то виджета, который отображается не всегда — тогда хранить данные в Vuex не стоит.

См. также

Подскажите, что делать дальше, после того как запрос ушел на сервер и мы получили ответ, что пользователь добавлен?

Это вопрос уже совершенно другого направления.

Создать и вызвать мутацию addUser для добавления нового пользователя в state?

Да. Actions для того и существует, чтобы вы могли выполнить какие-то асинхронные запросы, доп проверки, валидацию данных, определить нужно ли что-то сохранить в state и если нужно — что именно. Здесь вы можете добавить пользователя, проверить добавился ли он, выполнить дополнительный запрос на извлечение информации о нем. И тп.
А мутация — непосредственно алгоритм изменения состояния.

в чем тогда смысл нашего state?

Локальная, быстрая, реактивная копия данных с сервера на клиенте.

при любом действии все равно необходимо загружать данные с сервера

Это уже вопрос к серверу. И к его API. Есть много разных технологий синхронизации данных между сервером и клиентом.

На самом деле я не вижу ничего плохого в том, чтобы после добавления нового пользователя выполнить обращение и загрузить новый актуальный список.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@skepsikmod
Ну вы же получаете айдишник в ответе? Значит, коллизий быть не должно. А обновление данных... Ну так в любом случае надо делать, независимо от того, добавляли что-то или нет, если того задача требует
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы