Reputation: 2544
I just don't understand, in list.vue
I only trigger an list
action that asynchronously alters state.list
in updated
hook. items
is a computed property that only relies on state.list
. Why would this lead to infinite updated events?
I've found that if I move the code in updated
hook to watch
option like this:
watch: {
'$route': function () {
this.$store.dispatch('list')
},
},
infinite problem would disappear. But this would trigger updated
hook twice every time $route
change is watched, which I also don't know Why.
Simple demo is here. Related code
// main.js
var Vue = require('vue')
var app = require('./App.vue')
new Vue(app).$mount('#app')
// App.vue
<template>
<div id="app">
<h1>list bug test</h1>
<router-view></router-view>
</div>
</template>
<script>
import store from './store.js'
import router from './router.js'
export default {
store,
router,
}
</script>
// list.vue
<template>
<table>
<tbody>
<tr>
<th>title</th>
<th>actions</th>
</tr>
<tr v-for="(item, index) in items">
<td> {{item.title}} </td>
<td> submit </td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
updated: function () {
console.log('items.vue updated')
this.$store.dispatch('list')
},
mounted: function () {
console.log('items.vue mounted')
this.$store.dispatch('list')
},
computed: {
items: function () {
return this.$store.state.list.map(e => ( {title: e.ksmc } ))
},
},
}
</script>
// router.js
var router = new VueRouter({
routes:[
{
path:'/',
name: 'list',
component: listView,
},
],
})
// store.js
var store = new Vuex.Store({
state: {
error: undefined,
list: JSON.parse(localStorage.getItem('list')) || [],
},
mutations: {
list: function(state, list) {
state.list = list
},
error: function(state, error) {
state.error = error
},
},
actions: {
list (ctx, kwargs) {
setTimeout(() => {
ctx.commit('list', [{ksmc:'this is a title'}])
}, 1000)
},
},
})
Upvotes: 0
Views: 1137
Reputation: 34306
The updated
hook is called after the component's DOM has been updated due to a change in the component's data model (to cause the component to be re-rendered). Therefore you shouldn't change the component's state (async or not) inside this hook otherwise the state change will cause the component to re-render which will fire the updated
hook which will change the state... and so on.
The docs explain it well:
The component’s DOM will have been updated when this hook is called, so you can perform DOM-dependent operations here. However, in most cases you should avoid changing state inside the hook. To react to state changes, it’s usually better to use a computed property or watcher instead.
Upvotes: 2