Modifying state with Vuex mutation and Lodash.remove does not automatically cause a re-render in my Vue component

My component is designed to accept an array of Villager through its prop from a parent component, which retrieves the array from this.$store.state.

return this.$store.state.villages.find(value => value.id === 0).villagers

Afterwards, I use a this.$store.mutation commit to modify the array. While the mutation does take effect (as shown in the screenshot below), the component does not re-render and continues to display 3 items instead of 2.

There seems to be a disconnect in the reactive chain somewhere, but I am unable to pinpoint the issue. I assumed that the props value would trigger reactivity. Although the value has changed, the DOM does not reflect the update.

https://i.sstatic.net/fdg2o.png

Code Excerpts

I have extracted relevant portions for clarity:

store/index.ts

[...]
export default new Vuex.Store({
  state: {
    villages: [
      {
        id: 0,
        name: 'Peniuli',
        foundingDate: 20,
        villagers: [
          {
            id: '33b07765-0ec6-4600-aeb1-43187c362c5a1',
            name: 'Baltasar',
            bloodline: 'Gent',
            occupation: 'Farmer'
          },
[...]
   mutations: {
       disbandVillager (state, payload) {
         const villagerId = payload.id
         const village = state.villages.find(value => value.id === 0)
         console.debug('disbanding villager:', villagerId)
         if (!_.isNil(village)) {
           console.debug('before:', village.villagers)
           _.remove(village.villagers, function (n) {
             return n.id === villagerId
           })
           console.debug('after:', village.villagers)
         }
       }
     },
[...]

Village.vue

<template>
    <Villagers :villagers="playerVillage.villagers"></Villagers>
</template>
[...]
  computed: {
    playerVillage: function () {
      return this.$store.state.villages.find(value => value.id === 0)
    }
  }
[...]

Villagers.vue

<template>
  <v-container>
    <v-card v-for="villager in villagers" :key="villager.id">
      <v-row>
        <v-col>
          <v-card-title>Name: {{villager.name}}</v-card-title>
        </v-col>
        <v-col>
          <v-card-title>Bloodline: {{villager.bloodline}}</v-card-title>
        </v-col>
        <v-col>
          <v-card-title>Occupation: {{villager.occupation}}</v-card-title>
        </v-col>
        <v-col v-if="managable">
          <DisbandButton :villager="villager"></DisbandButton>
        </v-col>
      </v-row>
    </v-card>
  </v-container>
</template>

<script>
import DisbandButton from '@/components/village/DisbandButton'

export default {
  name: 'Villagers',
  components: { DisbandButton },
  props: [
    'villagers',
    'managable'
  ]
}
</script>

DisbandButton.vue

<template>
  <v-btn @click="disbandVillager" color="red">Disband</v-btn>
</template>

<script>
export default {
  name: 'DisbandButton',
  props: ['villager'],
  methods: {
    disbandVillager: function () {
      this.$store.commit('disbandVillager', { id: this.villager.id })
    }
  }
}
</script>

Answer №1

It appears that the issue lies in the usage of _.remove with lodash.

When using _.remove, Vue's reactivity system may not be triggered as intended due to its internal implementation.

You can refer to this link for more information: https://github.com/lodash/lodash/blob/ded9bc66583ed0b4e3b7dc906206d40757b4a90a/lodash.js#L3859

To ensure proper reactivity, consider using a custom filtering method like the following:

village.villagers = village.villagers.filter(function (n) {
  return n.id !== villagerId
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transferring information from a template to a view within Django

I am currently in the process of creating a bus reservation platform using Django. When a user searches for buses on a specific route, a list of available buses is displayed. Each bus in the list has a 'book' button that redirects to a new page c ...

Tips for implementing linear-gradient text in Android applications developed with React Native without using Expo

How can I implement linear-gradient text in react native mobile apps without using Expo? I want to apply a linear-gradient to change the text color. Is it possible to achieve this effect? If yes, please provide guidance on how to do it. If not, how do po ...

An error occurred during conversion: trying to convert an object to an array

After reading numerous articles about this issue and trying multiple solutions, I am still unable to resolve it! I have been stuck with this error for the past 3 days and I'm hoping someone can assist me. Thank you in advance for any help! My situati ...

Selecting a different option triggers the retrieval of data

Hello, I want to create a function that returns the index when a user changes the option selection. For example, if the user selects the second option, it should return 2. Here is my code: $('.selectContainer').on('change', fun ...

Positioning of SVG text along the y-axis

https://i.sstatic.net/FkBRo.png In my project, I am creating a population pyramid using d3 in combination with react. While d3 handles the calculations, react is responsible for rendering the DOM elements. Everything is going smoothly so far, except for p ...

Changing the structure of elements in an array using JavaScript

I am seeking a way to convert an array of strings, which represent dates in the format of 201001 ,201002, into something more readable like 2010 January, 2010 February. Do you have any suggestions on how to achieve this? var Array = ["201005", "201006", " ...

calling object functions using additional parentheses

After reviewing the passport.js documentation, I came across this piece of code: app.get('/login', function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) { return next(err); } if (!u ...

Why is it that my innerHTML function refuses to work no matter how much I try to troubleshoot it?

I am trying to dynamically add letters from the alphabet and numbers when I click a button: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Add Letters and Numbers</title> ...

Here's a unique version: "Discovering how clients can easily connect to a new room using socketio

There are 5 rooms on my server named "A", "B", "C", "D", and "E." Server-Side In the server side code: io.on('connection', (socket) => { console.log('New user connected'); socket.on('disconnect', () => { ...

Resize an image to precisely match the height of the text automatically

I am facing a challenge where I want to embed an image inline with text, while ensuring that it matches the height of the text. I have tried using <img src="img.jpg" height=16> and also <img src="img.jpg" height="100%">, but the former does not ...

What is the best way to arrange objects within an array based on a specific element contained in another array of objects?

Suppose we have two arrays of objects named per and con. The goal is to sort the per array in ascending order based on the continent values from the con array. How can we achieve this? By using the sort and find functions exclusively. Below is the code sni ...

"Enhance the visual appeal of your Vue.js application by incorporating a stylish background image

Currently, I am utilizing Vue.js in a component where I need to set a background-image and wrap all content within it. My progress so far is outlined below: <script> export default { name: "AppHero", data(){ return{ image: { bac ...

Seamless transition of lightbox fading in and out

Looking to create a smooth fade in and out effect for my lightbox using CSS and a bit of JavaScript. I've managed to achieve the fading in part, but now I'm wondering how to make it fade out as well. Here is the CSS code: @-webkit-keyframes Fad ...

Having trouble with React JS BrowserRouter not routing correctly when used with Express JS and Nginx proxy

I am facing an issue where I need to send parameters to a React component through the URL. This works perfectly fine when I test it in my localhost development environment. However, the problem arises when I deploy the React app to my live server (). The ...

Challenges arise when using Django Channels in conjunction with signals

I have a Vue script that connects to Django to retrieve notifications and update the notification count in a badge. My Django setup includes Django channels version 4, uvicorn 0.26, and websockets 12.0. I use a Django signal to trigger the update_notificat ...

What is the best way to arrange the elements of an array based on a specified value?

Is there a way to develop a function that can organize an array of data based on the value of a specified field? Suppose the field consists of three numbers: 1, 2, 3. The idea is that upon providing a certain value to the function, it will rearrange the ta ...

What is the best way to switch text color when the background changes?

Is there a way to dynamically change the color of a text logo to make it readable over differently colored backgrounds, such as on a slider or scroll down effect? While one approach could involve finding the dominant image color, this may be slow and ineff ...

Unable to retrieve props from server-side page to client-side component in a Next.js application router

Currently, I am utilizing app router alongside Next.js version 13.5. Within my /dashboard page (which is a server component), there is an ApiKeyOptions client component embedded. However, when attempting to pass props from the dashboard page to the ApiKeyO ...

Why is the Google Maps API not displaying the map once the app is deployed on Heroku?

const express = require('express'); var app = express(); var bodyParser = require('body-parser'); var exphbs = require('express-handlebars'); var cors = require('cors'); //setting up the view engine app.engine(&apos ...

Display or conceal objects within a 3D model with an HTML checkbox

I have utilized JavaScript, CSS, and Three.js to create a 3D model. The project comprises a total of 5 JS files, 1 CSS file, and 1 HTML file. Here is an overview of the model: [] Showers have been incorporated for each cubicle, which should only be vis ...