I have a state object being passed through as a prop from another component. I receive the state as expected. I then store the props in a toRef() for reactivity.
What I want to happen is when the data in state changes, I want to data in the browser to update. As it is right now, the data does get updated in the vue dev tools and I do see the state object change but the browser does not reflect the changes until I manually refresh the browser, which is an undesired result.
Why is this happening:
Component:
<template>
<div class="show-products">
<Product
v-for="data in products"
:key="data.id"
:product="data"
/>
</div>
</template>
<script>
import {computed, onMounted, toRefs, watch } from "vue";
import {useStore} from "vuex";
export default {
components: {Product},
props: {
state: Object
},
setup (props) {
const store = useStore();
const products = computed(() => store.getters.getProducts);
let stateRef = toRefs(props).state;
onMounted(() => {
store.dispatch('getProducts');
});
watch(stateRef, (currentState, prevState) => {
if (currentState.length !== prevState.length) {
store.dispatch('getProducts');
}
})
return {
Product,
products,
}
}
}
</script>
Observing the array length requires a deep watcher, so make sure to set the deep flag:
watch(stateRef, (currentState, prevState) => {/*...*/}, { deep: true })
Also, the watcher callback only receives the data references, so if you're only mutating the original array (e.g., via push() or pop()), the currentState and prevState arguments will be the same reference, which would defeat the length check for differences.
A potential solution is to remove the length check, and always dispatch the getProducts action in the watcher:
// ProductList.vue
watch(stateRef, (currentState, prevState) => {
store.dispatch('getProducts')
}, { deep: true })
Another solution that does not require a deep watcher is to assign a new array to state instead of using push()/pop() on the original array:
// Parent.vue
addState(newValue) {
state.value = [ ...state.value, newValue ]
}
demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With