Docs aren't clear enough about reactivity in computed properties


#1

Reading the docs about computed properties, it is said:

A computed property will only re-evaluate when some of its dependencies have changed.

It’s kind of misleading because it suggests that any dependency change will make the propertie re-evaluate. This is partially false as only the dependencies directly used in the returned value are taken into account.

Exemple (this is a vuex getter exemple, but it basically works the same):

// does NOT work (media isn't reactive)
media: (state, getters) => id => {
    const media = state.medias.find(baseMedia => baseMedia._id === id);

    return {
        ...media,
        ownMedia: media.userId === state.user._id,
    };
}

// works
media: (state, getters) => id => {
    return {
        ...state.medias.find(media => media._id === id),

        // functions allow to reference own object's properties
        ownMedia() { return this.userId === state.user._id }
    };
}

#2

I’m not really certain what isn’t working for you. Can you provide a codepen as an example?

For instance, this works fine for me:


#3

This statement is not correct. If that doesn’t work in an instance auch as the one you shared, that would be a bug.

I couldn’t test the code you provided yet, but that type of thing is done in computed properties everyday but hundreds of devs, so I would be surprised if this was a bug in the reactivity system.

Can you share how you use that function returned from the getter?


#4

Heys guys,

Thank you very much for your prompt answers. I realize I might have spoken a bit too fast.
Actually the problem was due to an async API call and I was struggling with undefined state due to async actions.

media: (state, getters) => id => {
    // here state.media isn't immediately defined
    const media = state.medias.find(baseMedia => baseMedia._id === id);

    return {
        ...media, // so media is undefined here
        ownMedia: media.userId === state.user._id
    };
}

As media const wasn’t defined, I ended up with errors preventing vue to execute as it should, hence my falsy assumption with the whole reactivity and return thing.

I ended up testing for state values at the begining and returning an empty object if state isn’t defined yet:

media: (state, getters) => id => {
    if (!state.medias) return {};
    const media = state.medias.find(baseMedia => baseMedia._id === id);

    return {
        ...media,
        ownMedia: media.userId === state.user._id
    };
}

I feared that if (!state.medias) return {}; might make the getter unreactive to state change, but it does not. I don’t know if it’s the way to handle things, if it’s not, I’d be glad if you can enlighten me.

Thanks again and sorry for posting such a confusing assertion in the first place.