Home > Enterprise >  Vuex store updating all instances, I only want current instance updated
Vuex store updating all instances, I only want current instance updated

Time:01-13

I'm building a simple blog page where users can like and dislike comments. My current issue is whenever user hits "addLike", or "subtractLike" methods all the comment likes are being updated not just the current one being clicked.

store:

export const state = () => ({
  comments: [
    {
      id: 1,
      likes: 0,
      name: 'amyrobson',
      img: '/img/avatars/image-amyrobson.png',
      post: `Impressive! Though it seems the drag feature could be improved.
              But overall it looks incredible. You've nailed the design and the
              responsiveness at various breakpoints works really well.`,
    },
  ],
})

export const mutations = {
  pushComment(state, comment) {
    state.comments.push(comment)
  },
  addLikes(state) {
    state.comments.forEach((element) => element.likes  )
  },
  subtractLikes(state) {
    state.comments.forEach((element) => element.likes--)
  },
}

component:

 <button @click="addLike">
        <img src="/img/icon-plus.svg" />
      </button>

      <p >{{ comment.likes }}</p>

      <button
        @click="subtractLike">
        <img src="/img/icon-minus.svg" />
      </button>

<script>
export default {
  data() {
    return {
      reply: false,
    }
  },
  },
  methods: {
    addLike() {
      this.$store.commit('comments/addLikes')
    },
    subtractLike() {
      this.$store.commit('comments/subtractLikes')
    },
  },
}
</script>

CodePudding user response:

That is because you're incrementing the likes for all comments regardless of their IDs. In order to increment the link for a specific comment, you need to pass some kind of identifier that will identify your comment. That identifier should be unique: in this case let's assume that the id field is unique.

Then, in your component you will need to commit the mutation with this bit of information (the identifier):

<button @click="addLike(comment.id)">
  <img src="/img/icon-plus.svg" />
</button>

<p >{{ comment.likes }}</p>

<button @click="subtractLike(comment.id)">
  <img src="/img/icon-minus.svg" />
</button>

<script>
export default {
  data() {
    return {
      reply: false,
    }
  },
  },
  methods: {
    addLike(id) {
      this.$store.commit('comments/addLikes', id)
    },
    subtractLike(id) {
      this.$store.commit('comments/subtractLikes', id)
    },
  },
}
</script>

Then you will need to update your commit definition to include that identifier. Use that identifier to find the comment whose like property you want to increment/decrement:

addLikes(state, id) {
  const foundComment = state.comments.find(comment => comment.id === id);
  if (foundComment) foundCommment.likes  ;
},
subtractLikes(state, id) {
  const foundComment = state.comments.find(comment => comment.id === id);
  if (foundComment) foundCommment.likes--;
},

p/s: Remember that objects in your array is by reference, so foundComment is simply a reference to the original comment object in state.comments, which allows you to mutate it directly.

  •  Tags:  
  • Related