Using the spread operator in a component's render function could potentially lead to an endless update loop

Although this issue has been addressed before in a discussion about the "You may have an infinite update loop in a component render function" warning in Vue component, the solution provided did not resolve my problem.

I am seeking assistance to understand what might be causing the issue in my case.

<template>
  <div>
    <template v-for="listing in sortedListings">
      <listing
        :key="listing.uuid"
        :listing="listing"
        :highlight-color="listing.highlight ? getHighlightColor() : null"
      />
    </template>
  </div>
</template>

<script>
import Listing from '@/components/Listing'
export default {
  components: {
    Listing,
  },
  data: function () {
    return {
      highlightColors: this.getHighlightColors(),
      listings: [
        {
          uuid: '658f325f-33c8-455b-98f6-27eb4eaa16a0',
          title: 'Cursus Nullam Amet Tortor',
          location: 'Remote',
          url: 'http://example.net/birds',
          hours_week: 20,
          tags: ['django', 'python', 'flask'],
          logo: 'https://logo.clearbit.com/apple.com',
          company_name: 'Apple',
          show_logo: 1,
          highlight: 0,
          stick_top: 0,
        },
        // additional listing items...
      ],
    }
  },
  computed: {
    sortedListings: function () {
      return [...this.listings].sort(function (a, b) {
        return b.stick_top - a.stick_top
      })
    },
  },
  methods: {
    getListings: async function () {},
    getHighlightColors: function () {
      return this.shuffleArray([
        '#E3F2FD',
        '#E8EAF6',
        '#FFEBEE',
        '#E0F2F1',
        '#E8F5E9',
        '#FFF3E0',
        '#FFFDE7',
      ])
    },
    getHighlightColor: function () {
      if (this.highlightColors.length === 0) {
        this.highlightColors = this.getHighlightColors()
      }
      return this.highlightColors.shift()
    },
  },
  mounted: function () {
    this.getListings()
  },
}
</script>

In the computed property sortedListings, I have already implemented [...this.listings].

Answer №1

When using the spread operator to copy an array, it's important to note that it doesn't create a deep clone. Additionally, if the sort method is used on the original array within a computed property, it can lead to an infinite loop. To avoid this issue, consider adding a method for deep cloning objects like the one mentioned in this reference:

...

 computed: {
    sortedListings: function () {
      return this.deepCopy(this.listings).sort(function (a, b) {
        return b.stick_top - a.stick_top
      })
    },
  },
  methods: {
   deepCopy(src) {
     let target = Array.isArray(src) ? [] : {};
     for (let prop in src) {
      let value = src[prop];
       if(value && typeof value === 'object') {
        target[prop] = deepCopy(value);
       } else {
        target[prop] = value;
      }
   }
     return target;
  }
  ,
    getListings: async function () {},
...

Answer №2

The function getHighlightColor() is causing an infinite loop.

This situation perfectly demonstrates why it can sometimes be problematic (though not always) to bind a method in the template. When a method modifies a model, Vue must re-render the component. This, in turn, triggers the method again, leading to further changes in the model and subsequent re-renders of the component, creating a continuous cycle.

A similar outcome can be achieved through this demo, but not if you utilize computed properties directly in the template:

new Vue({
  el: "#app",
  data() {
    return {
      arr: [1,2,3,4,5]
    }
  },
  methods: {
    change: function () {
      return this.arr.shift();
    },
  },
  computed: {
    test() {
      return this.arr.shift();
    }
  }
});
<div id="app">
  <div>
    {{ change() }}
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

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

Troubleshooting multiple element visibility problems with jQuery

Please take a look at the code snippet below. $(document).ready(function(){ $(".like-btn").hover(function() { var rowid = $(this).attr("data-rowid"); $(".reaction-box[data-rowid='" + rowid + "']").fadeIn(100, function() { $(".reaction ...

Combining two variables in AngularJS seamlessly, without explicit instruction

In the realm of Controllers resides my beloved home.js: angular.module("HomeApp", ["BaseApp"]) .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) { var self = this; self.posts = BaseServ ...

Are these two sections of my code distinctive in functionality? Do they both address potential errors in the same manner?

After receiving some helpful suggestions on my code from a user on stack overflow, I decided to revisit and make improvements. However, I am now questioning whether the changes I made handle errors in the same way as the original code. This is my initial ...

Finding the label that is linked to the current DIV or textarea by its "for" property

I am working on a project that involves two elements - a textarea and a div. Each element has a label attached to it using the "for" attribute in HTML. <textarea id="txta_1" class="txta" cols="40" rows="3" onkeyup ...

Unable to use addEventListener on media queries exceeding 768px

When testing the site on Firefox 49 and Chrome 63, I encountered the same issue. Clicking on each card worked fine on iPhone4, Galaxy 5, and iPhone 8 using Chrome. However, after switching orientations from 640px to 320px portrait view, the top card would ...

Obtain the bounding box of an SVG element while it is not visible

I've been grappling with this issue for more than a day now, but I'm still unable to find a solution. My challenge lies in the need to scale an SVG image for responsive design purposes. Since I have to manipulate the SVG code on the client side, ...

Adding a distinct key and its corresponding value to an array in Vue for a unique

I am attempting to add key-value pairs into an array while ensuring their uniqueness. Currently, I am trying the following approach: for (const [key, value] of Object.entries(check)) { console.log(`${key}: ${value}`); this.inputFields. ...

Bringing in d3js into Angular 2

Is there a way to successfully import d3js into an Angular2 project? I have already installed d3js using npm and added it to my systemJs, but am encountering a traceur.js error. I also attempted to just use the latest cdn in a script tag and tried import * ...

HighStock chart malfunctioning with inaccurate epoch datetime display

I am working on a project that involves creating a dynamic Highstock chart to showcase the daily influx of emails. The data is stored in a JSON file that gets updated every day, and you can see a snippet of it below: [{ "name": "Month", "data": [147199320 ...

Encountered difficulty accessing the controller ActionResult from JavaScript代码

Resolution: After thorough investigation, I successfully identified and resolved the issue. Surprisingly, it was not related to the Javascript or Controller code as initially anticipated. The root cause stemmed from a .dll file that was causing discrepanci ...

Having trouble setting the image source in HTML with Node.js

I am a beginner with nodeJS and I am having trouble setting the src attribute of an img tag in my client side html. My node server is running on port 3000 and everything works fine when I visit http://localhost:3000. Here is the code from my server.js fil ...

What is the syntax for accessing a nested object within the .find method?

Currently building an application in node.js. I am struggling with referencing the "email" element in the "userData" object within the Order model when using the find method. Any suggestions on how to properly refer to it? Order model: const orderSchema = ...

When the React application loads, loadingbar.js will be mounted initially. However, as the props or states are updated, the object

I recently made the switch from using progressbar.js to loadingBar.js in my React application for widget progress. Everything was working smoothly with progressbar.js, but once I switched to loadingBar.js, I encountered a strange issue. After the page load ...

The built-in functions of Wordpress are not able to be identified in the ajax PHP file

As a newcomer to Wordpress development, I am facing challenges with implementing ajax on my WordPress site. I am currently working on a plugin that requires the use of ajax. However, my php file (xxxecommerce.ajax.php) is not recognizing the built-in Word ...

How can I display several custom markers that are constantly updating on a Google map with MySQL and PHP?

Currently, I am using the following code to generate markers on a Google map by retrieving data from a database. However, the issue I am facing is that it only generates one marker instead of all the markers stored in the database. & ...

turning every input field's border to red if none of them were filled out at least once

I struggle with javascript and need some help. I have a form with multiple input fields, and I want to ensure that the user fills in at least one of them. I found code that triggers an alert message if the user does not fill in any fields, but I would pref ...

JavaScript: Locate the HTML Attribute that Matches an ID

If you want to use just JavaScript, without relying on libraries like JQuery, how can you retrieve the data attribute associated with a specific Id? For example: <div id="id-test" data-qa="data-qa-test"> </div> Input: &quo ...

How can I transform this imperative reducer into a more declarative format using Ramda?

I am currently working with a reducer function that aggregates values in a specific way. The first argument is the aggregated value, while the second argument represents the next value. This function reduces over the same reaction argument, aggregating th ...

What is the best method for extracting a particular value from my dataset?

I'm interested in creating a variable that stores the IsUserSiteOwner value from the data. Can someone help me with this? Any suggestions on how I can achieve this task? ...

I'm curious if the response order will mirror the URL order in my situation

QUERY: Upon reviewing the following link: Promise.all: Order of resolved values I am doubtful about its relevance to my specific scenario. Can I always expect responses to be in the same order as urls? EXAMPLE: var urls = []; for (var i = 0; i < d ...