【问题标题】:Vuex store not updated when called from promise resolution从承诺解决方案调用时,Vuex 商店未更新
【发布时间】:2018-04-18 12:07:14
【问题描述】:

我有一个绑定到 vuex 数据存储并通过 mapGetters 帮助器作为计算属性公开的数组。这个数组叫做items,我在组件的created()钩子中调用了一个REST API来更新它。我为此执行的 vuex 操作返回一个承诺,在该承诺中访问 API 并在解析之前调用 mutator(更新 items 数组)。我对 Promise 的理解告诉我,我的 then 调用应该在异步操作完成后安全地发生,但是如果我尝试从 Promise 解析中访问 items,尽管数组肯定是由 API 调用填充的,但它是空的。为什么这不符合我的预期?

代码已经全部结束,但这里是相关部分

组件:

  computed: {
    ...mapGetters({
      items: 'allHistoryItems'
    }),
// ...
  created () {
    this.$store.dispatch('fetchList').then(console.log(this.items))
  }

行动:

  fetchList: ({ commit }) => {
    return new Promise((resolve, reject) => {
      fetchList().then(response => {
        commit(types.FETCH_LIST, response.data)
        resolve(response)
      })
    })
  }

我可以从组件访问 API 响应,但如前所述,items 是空的。直到 Promise 解决后才开始反应?

【问题讨论】:

  • Avoid the promise constructor anti-pattern - 话虽如此,“动作”如何改变项目?我看不到连接
  • ahhh .then(console.log(this.items)) ... 应该是 .then(() => console.log(this.items)) ... .then 需要一个函数作为参数,而不是调用 console.log 的结果(顺便说一下未定义)跨度>
  • 我会检查这篇文章。 Items 被映射到一个 getter,该 getter 操作并返回 API 获取的列表。
  • 忽略我的第一条评论,你犯的错误在我的第二条评论中
  • 想想它就是这么基本的东西。我稍后会对其进行测试,但将其变成答案,我会接受它。

标签: javascript vue.js promise vuex


【解决方案1】:

总之

created () {
    this.$store.dispatch('fetchList').then(console.log(this.items))
}

created被调用时,它会执行:

this.$store.dispatch('fetchList')

立即跟随

console.log(this.items)

什么都不用等待,那么,当this.$store.dispatch('fetchList') 解析时,.then 就像.then(undefined) 一样被调用...因为console.log(this.items) 返回undefined

把这个改成

created () {
    this.$store.dispatch('fetchList').then(() => console.log(this.items));
}

作为奖励 - 删除承诺构造函数反模式:

fetchList: ({ commit }) => fetchList() 
    .then(response => {
        commit(types.FETCH_LIST, response.data);
        return response;
    }
);

【讨论】:

    【解决方案2】:

    我认为您的新 Promise 构造是多余的。如果它正在做你想做的事,请检查这个简单的例子:

    var store = new Vuex.Store({
      state: {
        hero: []
      },
      mutations: {
        updateHero (state, payload) {
    
          state.hero = payload
        }
      },
      actions: {
        async loadHero ({commit}, payload) {
          var response = await fetch('https://swapi.co/api/people/1/')
          commit('updateHero', await response.json())
        }
      }
    })
    
    new Vue ({
      el: '#app',
      store,
      computed: {
        hero () {
          return this.$store.state.hero
        }
      },
      methods: Vuex.mapActions(['loadHero'])
    })
    [v-cloak] {
      display: none;
    }
    <div id="app">
      Hero name is: <span v-cloak>{{ hero.name }}</span><br>
      <button @click="loadHero">Load hero personal data</button>
    </div>
    
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vuex"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-31
      • 2018-08-19
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      相关资源
      最近更新 更多