Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactivity problem with mapGetters only on first load

I am using the mapGetters helper from VueX but i have some problem only on the first load of the page, it's not reactive... Let me show you :

my html template triggering the change :

<input type="number" value="this.inputValue" @change="this.$store.dispatch('setInputValue', $event.target.value)">

my store receiving the value

{
    state: {
        appValues: {
            inputValue: null
        },
    },
    getters: {
        getInputValue: (state) => {
            return state.appValues.inputValue;
        },
    },
    mutations: {
        setInputValue(state, value) {
            state.appValues.inputValue = value;
        },
    },
    actions: {
        setInputValue(context, payload) {
            return new Promise((resolve, reject) => {
                context.commit('setInputValue', payload);
                resolve();
            });
        },
    }
}

and then my component listening the store :

import {mapGetters} from 'vuex';

computed: {
    ...mapGetters({
        inputValue: 'getInputValue',
    }),
}
watch: {
    inputValue: {
        deep: true,
        immediate: true,
        handler(nVal, oVal) {
            console.log("inputValue", nVal, oVal);
        }
    },
}

So now, when i first load the page I get this console.log "inputValue" null undefined which is totally normal because as I have nothing in my store it gaves me the default value null.

But now it's the weird part. I start changing the input value and I don't have nothing appearing in my console. Nothing is moving...

Then I reload the page and on the load I get this console.log "inputValue" 5 undefined (5 is the value I entered previously) so as you can see, when I was changing the input previously, it was well keeping the value in the store but the computed value was not updating itself...

Ans now, when I change the value of the input I have my console log like this "inputValue" 7 5 so it's working as I would like it to work from the start...

What do I do wrong? Why on the first load the computed value not reactive?

Thanks for your answers...

like image 748
Simon Trichereau Avatar asked Nov 06 '22 15:11

Simon Trichereau


1 Answers

I think the best way to solve this issue is to store a local variable with a watcher, and then update vuex when the local is changed:

On your component:

<input type="number" v-model="value">

data() {
    return {
        value: ''
    };
},

computed: {
    ...mapGetters({
        inputValue: 'getInputValue'
    })
}

watch: {
    value(value){
        this.$store.dispatch('setInputValue', value);
    },

    inputValue(value) {
        console.log('inputValue', value);
    }
},

created() {
    // set the initial value to be the same as the one in vuex
    this.value = this.inputValue;
}
like image 60
Rich Avatar answered Nov 12 '22 17:11

Rich