Vue.js Состояние Vuex никогда не обновляется с помощью push ()

#vue.js #vuex

#vue.js #vuex

Вопрос:

У меня есть хранилище Vuex, которое управляет массивом ( state.all ), и у меня есть кнопка, которая вызывает действие Vuex, которое выполняет HTTP-вызов, а затем добавляет данные в ответ на state.all путем изменения. Однако состояние никогда не обновляется, и компоненты никогда не обновляются.

Чтобы доказать, что я не сумасшедший, я использовал два alert() s внутри мутации, чтобы убедиться, что я знаю, где я нахожусь в коде. alert() s всегда запускались с правильными значениями.

Вот усеченное хранилище Vuex (это модуль):

 const state = {
    all: []
}

// actions
const actions = {
    ...
    runner ({ commit, rootState }, { did, tn }) {
       HTTP.post(url, payload)
           .then(function (response) {
               commit('setNewConversations', response.data)
           })
       })
    }
}

const mutations = {
    ...
    setNewConversations(state, new_conv) {
        for (let new_c_i in new_conv) {
            let new_c = new_conv[new_c_i]
            alert(new_c) // I always see this, and it has the correct value
            if (!(new_c in state.all)) {
                alert('I ALWAYS SEE THIS!') // testing
                state.all.push(new_c)
            }
        }
    }
    ...
}
  

Когда я захожу, чтобы протестировать это, я вижу свои два alert() параметра, первый со значением, которое я ожидаю, а второй со значением «Я ВСЕГДА ВИЖУ ЭТО!», но с моим v-for компонентом ничего не происходит, и состояние никогда не обновляется, несмотря на state.all.push() .

Каков следующий шаг к устранению этой проблемы? В консоли JS нет ошибок, и я не могу понять, по какой причине состояние не будет обновлено.

Спасибо!

Комментарии:

1. Вы уверены, что это не обновляет хранилище? Может быть, по какой-то причине представление просто не обновляется?

2. Теперь, когда я удаляю свой alert() , он внезапно начинает работать. Теперь это проблема, которая возникает только изредка. Что я мог бы сделать, чтобы выяснить, почему это происходит?

3. У вас vue devtools установлено расширение / плагин / что угодно в вашем браузере, это отличный способ отслеживать состояние вашего vuex

Ответ №1:

Одно из возможных решений — вместо перехода к текущему значению состояния сохранить предыдущее значение state.all в новом массиве и внести новые изменения в этот новый массив.

После завершения присвойте этому новому массиву state.all , как показано ниже.

  setNewConversations(state, new_conv) {
    const prevState = [...state.all];
    for (let new_c_i in new_conv) {
        let new_c = new_conv[new_c_i]
        if (!(new_c in prevState)) {
          prevState.push(new_c);
        }
    }
    state.all = prevState;
}
  

Комментарии:

1. С какой стати мне использовать const в этой конкретной ситуации?

2. @David почему бы и нет? Вы можете помещать данные в массив const, вы знаете

3. @downvoter, я действительно не возражаю против понижения, но я был бы признателен, если бы вы оставили комментарий / причину понижения, чтобы я мог также учиться и не повторять ту же ошибку в следующий раз. @David, вы можете изменить объявленный массив const , если вы не переназначаете его.

4. @AnaLizaPandac не уверен, почему вы были отклонены, кто-то, должно быть, не понимает vue / javascript, потому что это действительно правильный ответ

Ответ №2:

Учитывая, что вы сказали, что удаление предупреждения заставляет его работать, я задаюсь вопросом, не наблюдаете ли вы значение в неправильном месте. Я не могу быть уверен в том, что вы указали.

Помните, что Javascript является однопоточным, и ваша мутация должна завершиться, прежде чем сможет выполняться любой другой код реактивности, введенный Vue.

Если вы действительно хотели, чтобы значение отображалось до завершения мутации, вы, вероятно, могли бы вызвать Vue.nextTick(() => alert(...)) , но лучший ответ — проверить наличие обновлений где-нибудь в другом месте, например, в вычисляемом, который вызывает средство получения состояния.весь массив.

(Кстати, я обнаружил, что использование любого из них console.log(...) или vue-dev-tools намного быстрее, чем alert() для произвольной отладки.)