2

I get a very strange error which I can't locate.

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

I am using vuex in strict mode. Despite the error I am not mutating any vuex store state outside mutation handlers. The component is not using vuex at all. I created a test component that does not use anything like below.

<template>
  <div>
    TEST COMPONENT
  </div>
</template>  
<script>
export default {
  name: 'testComponent',
  props: ['testProp'],
}
</script>

As soon I add the props part I get the error. I am not able to represent the whole project here or reproduce it. But there is nothing special anyway.

SMAKSS
  • 9,606
  • 3
  • 19
  • 34
Skeletor
  • 3,201
  • 4
  • 30
  • 51
  • These sound unrelated. How is this component used? – Dan Apr 24 '20 at 12:17
  • actually I reduced it. I tracked it down untill I found out that the error appears after I add the props part. so it is just a simple test component. may be the error is coming from another part. the vuex itself perhaps. but get no error untill I add the props. – Skeletor Apr 24 '20 at 12:33
  • 1
    But there is no inherent connection between a random component's props and Vuex. For example, if I start a new project with Vuex and use this component here, I will not get this error. So this is not enough information for anyone to make a guess, and we can't see your Vuex or how this component is used. Have a look at the [question guide](https://stackoverflow.com/help/minimal-reproducible-example) – Dan Apr 24 '20 at 12:48
  • What exactly do you pass in testProp? If this is a prop from a vuex store so this is it! – Anatoly Apr 24 '20 at 16:09
  • @Anatoly it does not matter what I pass. even a simple string does the same. when I remove the props then I dont get the error. – Skeletor Apr 24 '20 at 16:28

3 Answers3

2

For me it was because I did routes = this.$router.options.routes for setting up Navigation.

The solution was routes = JSON.parse(JSON.stringify(routes)) before assigning routes to state.

TariqK
  • 21
  • 3
1

Well after some debugging I found out that it actually was caused by vuex and vue-router.

Actually I could find this before if I just looked detailed into the trace of the error. The vue-router.esm.js?8c4f:2279 section was giving a hint but I could not see it (lack of vue experience I guess).

...
reactiveSetter  @   vue.runtime.esm.js?2b0e:1055
normalizeProps  @   vue.runtime.esm.js?2b0e:1449
mergeOptions    @   vue.runtime.esm.js?2b0e:1521
Vue.extend  @   vue.runtime.esm.js?2b0e:5159
extractGuard    @   vue-router.esm.js?8c4f:2279
eval    @   vue-router.esm.js?8c4f:2263
eval    @   vue-router.esm.js?8c4f:1968
eval    @   vue-router.esm.js?8c4f:1968
...

I was getting the the routes from the store and adding (addRoutes()) them to the route.

router.beforeEach((to, from, next) => {
...
    router.addRoutes([store.getters['route/getRoute']]);
...
}

But because it was passed by reference (and I guess the router was doing some changes on it) the error was rising. The route was trying to "mutate vuex store outside mutation hander"

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

I solved it by deep cloning (like below) it with lodash but could use other deepcloning as well.

let routeDeepClone = _.cloneDeep([store.getters['route/getRoute']]);
router.addRoutes(routeDeepClone);

Now it works very well. Hope it helps someone.

Skeletor
  • 3,201
  • 4
  • 30
  • 51
0

I was dumbfounded by this for a little while, but turns out it was something super silly. As the error suggests, we are modifying a Vuex state somewhere inadvertently. Possibly, you are doing an assignment without realizing it. My error was this:

  computed: {
    foo() {
      return this.model.bar.find(
        (obj) => obj.key = this.$route.params.baz
      )
    },
  }

Silly me, I was doing

obj.key = this.$route.params.baz

instead of

obj.key === this.$route.params.baz

The object was getting updated by reference instead of my intention of doing an equality check.

Murali Varma
  • 193
  • 2
  • 7