Search code examples
javascriptvue.jsvuex

Same Vue code is reactive in one sandbox and not in the other


I wanted to prepare minimum reproducible sandbox for my issue. I forked my previous sandbox and removed the code that was irrelevant for new case. But one feature stopped working and I have no idea why. The code looks the same and console.log shows the code is updated. Why does it work in one sandbox and does not work in the second?

The original sandbox: https://codesandbox.io/s/frosty-taussig-v8u4b Try to click on some button with numbers, it gets incremented instantly.

Minimized sandbox: https://codesandbox.io/s/nervous-breeze-ejznz. If you click on a button with number, nothing happens until you reload the screen.

I would like to understand this behaviour. I do not see a reason why the same source code behaves differently.

Mutation:

SET_VOTE: (state, payload) => {
  console.log("SET_VOTE");
  const { commentId, vote } = payload;
  const comment = state.comments[commentId];
  if (vote === 1) {
    comment.up += 1;
  } else {
    comment.down += 1;
  }
  console.log(comment);
}

Action:

COMMENT_VOTE: async (context, payload) => {
  console.log("COMMENT_VOTE", payload);
  const mutation = {
    commentId: payload.commentId,
    vote: payload.vote
  };
  context.commit("SET_VOTE", mutation);
}

Comment.vue

<b-button v-on:click="upvote" class="mr-1">
  {{ comment.up }}
</b-button>

async upvote() {
  await this.$store.dispatch("COMMENT_VOTE", {
    vote: 1,
    commentId: this.comment._id
  });
},

enter image description here


Solution

  • You forgot about a reactivity again. Use Vue.set to set a new prop in a comments state prop:

      Vue.set(state.comments, comment._id, comment);
    

    instead of

      state.comments[comment._id] = comment;