从承诺解决方案调用时,Vuex 商店未更新

Posted

技术标签:

【中文标题】从承诺解决方案调用时,Vuex 商店未更新【英文标题】:Vuex store not updated when called from promise resolution 【发布时间】: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 获取的列表。 忽略我的第一条评论,你犯的错误在我的第二条评论中 想想它就是这么基本的东西。我稍后会对其进行测试,但将其变成答案,我会接受它。 【参考方案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>

【讨论】:

以上是关于从承诺解决方案调用时,Vuex 商店未更新的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Vuex [Quasar] 访问商店

解决承诺后,视图中的数据未更新

Vuetify 组合框项目模板未使用 vuex 更新

如何在 vuex 的挂载函数中访问存储数据

VueJS Vuex - 解决状态变化的承诺?

Vuex 操作未将本地存储令牌添加到 Axios 调用后