davestewart / vuex-pathify

Vue / Vuex plugin providing a unified path syntax to Vuex stores
https://davestewart.github.io/vuex-pathify
MIT License
1.37k stars 57 forks source link

`store.set('property@subproperty', value)` errors with "infinite update loop in a component render function" #30

Closed iyerusad closed 6 years ago

iyerusad commented 6 years ago

Issue

store.set('property@subproperty', value) errors with "infinite update loop in a component render function"

however:

store.set('property', value) successfully sets.

Example

sampleView1.vue

<template>
<div>
  {{ $store.set('pagesviewed', true) }}
  <p>Value: {{this.pagesviewed}}</p>

</div>
</template>

<script>
import { sync } from "vuex-pathify";

export default {
  computed: {
    ...sync("*")
  }
};
</script>

vs

sampleView2.vue

<template>
<div>
  {{ $store.set('pagesviewed@test', true) }}
  <p>Value: {{this.pagesviewed.test}}</p>

</div>
</template>

<script>
import { sync } from "vuex-pathify";

export default {
  computed: {
    ...sync("*")
  }
};
</script>

image

Debug details:

[Vuex Pathify] Options:

Mapping (standard)

path : value state : value getters : value actions : setValue mutations : SET_VALUE

Settings

strict : true cache : true deep : 2

backend.js:1 vue-devtools Detected Vue v2.5.17

davestewart commented 6 years ago

Hey,

Thanks for the detailed bug response.

Is there a reason you're setting values in the template?

{{ $store.set('pagesviewed', true) }}
  <p>Value: {{this.pagesviewed}}</p>

My guess, and likely from the error message, is that this is causing the view to be updated then re-rendered, which causes it to be updated, and re-rendered, which causes it to be...

...you get the idea.

As for why one does it vs the other, I'm not sure, but as this is something you probably shouldn't be doing anyway, I'm not sure whether it warrants further investigation?

iyerusad commented 6 years ago

Heh, its what happens when you get a nice case of the stupid. New to Vue, new to JS. Thats on me - I tried setting it in script section as:

import store from "@/store/mainstore";
store.set('pagesviewed@test', true)

but am trying trying to avoid having to call import store from "@/store/mainstore"; in every vue file ($store doesn't appear to be available in the script portion). Similarly trying to find a way to not have to call

import { sync } from "vuex-pathify";
export default {
  computed: {
    ...sync("*")
  }
};

in every vue as well. I stumbled on this.$parent.somemethod and that has been handy for centralizing the methods into the app.vue in a simple SPA.

As an aside, I guess I am now curious why setting the property doesn't loop but setting the subproperty does.

davestewart commented 6 years ago

Aha :)

Looks like you have some fundamental errors with your assumptions / understanding.

To not import store make sure your root Vue instance has the store included, then access via this.$store but as you noticed, you can ONLY do this from within the component.

The reason $store doesn't appear to be available in the script portion, is because $store is a property of the component, i.e. this.$store which is added to the prototype chain when your component is created from the definition you're currently writing.

You will have to import vuex-pathify each time you want to use it. No way round that!

As for your use of $parent, that's a bit of an anti-pattern, unless you can guarantee that the components are tightly-coupled, for example a set of accordion components or something.

For centralising methods, you really do need to stick with importing! If you want them on individual components, you could also try mixins (see the docs).

Most of this stuff is about architecture and logic. Hacking like this when you a beginner (though I don't know if you are? Perhaps you know other languages?) is kind of expected I suppose, but you should be VERY careful about becoming comfortable with these "worst"-practice techniques. If you are a hobby programmer, you're no danger to anyone other than yourself, but if you're a professional, these kinds of hacks will quickly lead your colleagues to hate you!

Good luck :)

iyerusad commented 6 years ago

didn't realize that, thanks for the heads up.