【问题标题】:(Why) does .forEach() mutate vuex state?(为什么) .forEach() 会改变 vuex 状态吗?
【发布时间】:2022-01-10 21:38:51
【问题描述】:

我从我的 vuex 状态中获取了两组余额,并将它们合并到一个新的条目数组中。 为什么当我遍历 vuex 状态的 副本 时会引发错误?我错过了什么吗?

.filter() 返回一个新数组,因此coins 不再连接到 $state。

我没有改变 vuex 状态,而是我的副本。仍然警告我不要在突变之外对 vuex 存储进行突变。

如果这些分配是对 vuex 存储的实际引用,那么这是有道理的,但它们不是(或者它们是??)。我试图了解这里出了什么问题,但我不明白这里出了什么问题。我希望你们能提供帮助。谢谢!

filteredItems() {
      let coins = this.$store.state.wallet.balances.filter(( item ) => this.getCoinPropertiesByTicker(item.ticker).staking_available);
      const stakingCoins = this.$store.state.wallet.stakingBalances;
->    coins.forEach((coin) => {     // error happening here
        const stakingCoin = stakingCoins.user.stats.find((name) => name.ticker === coin.ticker)
        if (stakingCoin) {
          coin.totalAmount = {
            amt: new BigNumber(stakingCoin.balance).decimalPlaces(8).toString(),
            usd: new BigNumber(stakingCoin.balance_usd).decimalPlaces(2).toString()
          }
        }
      return coins
      }



[Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."

(found in <Root>)


vue.esm.js?a026:1897 Error: [vuex] do not mutate vuex store state outside mutation handlers.
    at assert (vuex.esm.js?2f62:90)
    at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:793)
    at Watcher.run (vue.esm.js?a026:4577)
    at Watcher.update (vue.esm.js?a026:4551)
    at Dep.notify (vue.esm.js?a026:739)
    at Object.reactiveSetter [as amountStaked30] (vue.esm.js?a026:1064)
    at eval (Staking.vue?3a4a:134)
    at Array.forEach (<anonymous>)
    at VueComponent.filteredItems (Staking.vue?3a4a:115)
    at Watcher.get (vue.esm.js?a026:4488)

【问题讨论】:

  • 你的数组中的对象是通过引用传递的:当你过滤一个数组时,它会创建一个新的数组实例,但是其中包含的对象都指向原始数组中的相同对象。
  • 错误发生在这里coin.totalAmount = {,如消息中所述不要在突变处理程序之外改变 vuex 存储状态,复制存储,改变值然后提交返回,或使用商店中的处理程序
  • 这里有一篇文章解释了指针的工作原理以及如何通过深度克隆来规避它们。像 Lodash 这样的库使这更容易。 digitalocean.com/community/tutorials/…
  • 是的,您需要使用突变而不是直接过滤您的商店。或者,如果你想避免额外的样板文件,我认为你可以 mapState vuex.vuejs.org/guide/state.html#the-mapstate-helper
  • @Ahmed Jaouadi splice 的作用与过滤器相同:它创建数组的浅表副本。 OP 需要深入研究克隆对象数组。

标签: javascript vue.js vuex


【解决方案1】:

正如其他人发布的(我不知道),数组内部的实际项目是对商店的引用,即使在将其分配给变量之后也是如此。

在我的例子中,我做了JSON.parse(JSON.stringify(this.$store.state.wallet.balances)).filter(( item ) =&gt; this.getCoinPropertiesByTicker(item.ticker).staking_available),它创建了一个深层副本,现在错误消失了。

谢谢!

【讨论】:

    猜你喜欢
    • 2017-08-01
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2018-12-29
    • 1970-01-01
    • 2016-02-02
    相关资源
    最近更新 更多