Vue.js infinite loop on component re-render

MarkMan

I'm trying to build tables based off a few selected properties from a previous component: I'm rendering a component called 'branch-comparison' to compare XML files and their properties and values. This component takes in two props:

selectedEnvs: An array of objects with a name and object

commonFiles: An array of files with a name and object

I'm using vue-tables-2 to build these tables. At the top of the template it runs a function called getProps() to generate a set of all possible properties from each file. I've hard coded 0 because currently I'm only letting the user choose 1 file at a time. It then goes through each file (only 1) and gets data for the main table and the comparison tables. They are virtually the same function (getHeadData and getTableData) but I've seperated them for now for further customization. The code is not that important for actually generating the tables, however something inside of them is causing my code to go in an infinite loop.

On the initial render of the component, there is never an infinite loop. Everything runs through, and doesn't break at all and works wonderfully. Once however the component has been rendered, and I make a change to the props, or even simply save the file in the editor and vue-cli hot reloads it, it goes into and infinite loop. All the data still get's generate fine and the component does as it's supposed to. But it loops through 101 times no matter what.

Things I've looked into:

Changing the data: I fully understand a component re renders on data change... however I don't believe I am changing any reactive data in any method call. I'm simply declaring it locally inside the function and returning it to that temporary variable. Also if this was the case, I believe it would go into an infinite loop on the initial component load, but this is not the case. It goes into the infinite loop only on a refresh or prop change.

Mutating the Vuex state: I looked into this but I am never changing the state of anything. I am simply accessing it in the getTableData and getHeadData methods. I then thought, perhaps assigning a variable to point to this state object is causing it to re render based on something accessing the state, so I tried instead of

this.$store.state.branchesToCompare[branchIdx].obj[env.name].app_config[this.commonFiles[fileIdx]].forEach(envProp
=> {

to use

var x = JSON.parse(JSON.stringify(this.$store.state.branchesToCompare[branchIdx].obj[env.name].app_config[this.commonFiles[fileIdx]])

then

x.forEach(envProp =>

but this still does not work.

If I comment out the code that calls getHeadData() and getTableData() it loops through the appropriate amount of times.

Here is the code.. I am still new to Vue so any more general suggestions I am more than open to:

 <template>
   <div id="BranchComparison">
      <div :set="info = getProps(0)">
         <div class="file" v-for="(file, fileIdx) in commonFiles" :key="(file, fileIdx)">
            <h3>{{ file }} </h3>
            <b-row :set="mainTable = getHeadData(fileIdx, info.props, info.columns)">
               <b-col class="mainBranch">
                  <h5 class="fileName"> {{ $store.state.branchSelection.split('.').slice(0, -1).join('.') }} <span style="font-size: 14px;">vs </span> </h5>
                  <v-client-table
                     :data="mainTable.data"
                     :columns="mainTable.columns"
                     :options="mainTableOptions"
                     size="small"
                  ></v-client-table>
               </b-col>
               <b-col class="compareBranch" v-for="(branch, branchIdx) in $store.state.branchesToCompare" :key="(branch, branchIdx)">  
                  <h5> {{ branch.name.split('.').slice(0, -1).join('.') }} </h5>
                  <v-client-table
                     :set="temp = getTableData(fileIdx, branchIdx, info.props, info.columns, mainTable)"
                     :data="temp.data"
                     :columns="temp.columns"
                     :options="temp.options"
                     size="small"
                  ></v-client-table>
               </b-col>
            </b-row>
         </div>
      </div>
   </div>
</template>

<script>

export default {

   props: ['selectedEnvs', 'commonFiles'],

   data(){
      return{
         mainTableOptions:{
            filterable: false,
            filterByColumn: false,
            perPage: 200,
            pagination: {
               show: false,
               dropdown: false
            },
            sortable: [''],
            resizableColumns: false,
         },
      }  
   },

   methods: {
      getTableData(fileIdx, branchIdx, props, columns, mainTable){

         var data = []

         var compareTableOptions = {
            filterable: false,
            perPage: 200,
            pagination: {
               show: false,
            },
            sortable: [''],
            hiddenColumns: ['Property'],
            resizableColumns: false,
            cellClasses: {}
         }


         props.forEach(prop => {
            var temp = { Property: prop }
            this.selectedEnvs.forEach(env => {
               var found = false;
               this.$store.state.branchesToCompare[branchIdx].obj[env.name].app_config[this.commonFiles[fileIdx]].forEach(envProp => {
                  if(envProp){
                     if (prop == envProp["@name"]) {
                        compareTableOptions.cellClasses[env.name] = []
                        compareTableOptions.cellClasses[env.name].push({
                           class: 'same',
                           condition: row => {
                              try{
                                 return row[env.name] == mainTable.data[i][env.name]
                              } catch{
                                 console.log('This is a different problem ')
                              }
                           }
                        })
                        found = true;
                        temp[env.name] = envProp["@value"]
                     }
                  }
               });
               if (!found){
                  temp[env.name] = 'Not found'
               } 
            })
            data.push(temp)
         });

         return {
            columns: columns,
            data: data,
            options: compareTableOptions
         }
      },

      getHeadData(fileIdx, props, columns){
         var data = []
         props.forEach(prop => {
            var temp = { Property: prop }
            this.selectedEnvs.forEach(env => {
               var found = false;
               this.$store.state.jsonObject[env.name].app_config[this.commonFiles[fileIdx]].forEach(envProp => {
                  if(envProp){
                     if (prop == envProp["@name"]) {
                        found = true;
                        temp[env.name] = envProp["@value"]
                     }
                  }
               });
               if (!found){
                  temp[env.name] = 'Not found'
               } 
            })
            data.push(temp)
         });

         return {
            columns: columns,
            data: data
         }
      },

      getProps(fileIdx){

         if(this.commonFiles.length == 0) return

         var columns = ['Property']
         var props = new Set()

         this.selectedEnvs.forEach((env, idx) => {
            columns.push(env.name)
            this.$store.state.branchesToCompare.forEach(branch => {
               branch.obj[env.name].app_config[this.commonFiles[fileIdx]].forEach(prop => {
                  if(prop){
                     props.add(prop["@name"])
                  }
               })
            });
            this.$store.state.jsonObject[env.name].app_config[this.commonFiles[fileIdx]].forEach(prop => {
               if(prop){
                  props.add(prop["@name"]);
               }
            });
         });

         var ret = { props: props, columns: columns }

         return ret;
      }
   }
}

</script>

What it produces

MarkMan

I've solved it. The code above is actually fine. Shortly before I posted the code, I was using a computed property in the v-for AND in the getHeadData(), what I think was happening was it was a nested computed property, and on the inner loop it recomputed it and then tried the outer loop again, and so forth. I'm still puzzled why it work on the initial render, but oh well. It is working now.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Infinite loop when using Vue component render function

From Dev

Infinite loop when using Vue component render function

From Dev

Vue warn]: You may have an infinite update loop in a component render function

From Dev

Render an image before loading the component in vue js

From Dev

Ember re render component

From Dev

Re-render view with component after destroy in Ember.js

From Dev

Re-render view with component after destroy in Ember.js

From Dev

error in adding numbers : You may have an infinite update loop in a component render function

From Java

Can you force Vue.js to reload/re-render?

From Dev

Vue.js re-render static content

From Dev

Node js infinite loop

From Dev

Re render a component with updated changes

From Dev

Vue.js - Reactivity component, not always re-rendering

From Dev

Watch $route.params.id does not trigger re-render of Vue component

From Dev

How to perform child component validation without infinite loop in react.js

From Dev

Mediaelement.js infinite loop

From Dev

JS - insertBefore() infinite loop with getElementsByTagName

From Dev

JS Bin while infinite loop

From Dev

JS Bin while infinite loop

From Dev

HTML & JS infinite background loop

From Dev

variable re-identification causing an infinite loop

From Dev

Re-render wicket component from backend

From Java

How to force Blazor to re-render a component

From Dev

Re-render wicket component from backend

From Dev

React/Redux component does not re-render

From Dev

Vue.js dont re-render after select element change

From Dev

function call within a vue js v-for directive makes the loop run into an infinite loop and I don't know why

From Dev

Component Inheritance with vue js

From Dev

Why does Vue render component incorrectly?

Related Related

  1. 1

    Infinite loop when using Vue component render function

  2. 2

    Infinite loop when using Vue component render function

  3. 3

    Vue warn]: You may have an infinite update loop in a component render function

  4. 4

    Render an image before loading the component in vue js

  5. 5

    Ember re render component

  6. 6

    Re-render view with component after destroy in Ember.js

  7. 7

    Re-render view with component after destroy in Ember.js

  8. 8

    error in adding numbers : You may have an infinite update loop in a component render function

  9. 9

    Can you force Vue.js to reload/re-render?

  10. 10

    Vue.js re-render static content

  11. 11

    Node js infinite loop

  12. 12

    Re render a component with updated changes

  13. 13

    Vue.js - Reactivity component, not always re-rendering

  14. 14

    Watch $route.params.id does not trigger re-render of Vue component

  15. 15

    How to perform child component validation without infinite loop in react.js

  16. 16

    Mediaelement.js infinite loop

  17. 17

    JS - insertBefore() infinite loop with getElementsByTagName

  18. 18

    JS Bin while infinite loop

  19. 19

    JS Bin while infinite loop

  20. 20

    HTML & JS infinite background loop

  21. 21

    variable re-identification causing an infinite loop

  22. 22

    Re-render wicket component from backend

  23. 23

    How to force Blazor to re-render a component

  24. 24

    Re-render wicket component from backend

  25. 25

    React/Redux component does not re-render

  26. 26

    Vue.js dont re-render after select element change

  27. 27

    function call within a vue js v-for directive makes the loop run into an infinite loop and I don't know why

  28. 28

    Component Inheritance with vue js

  29. 29

    Why does Vue render component incorrectly?

HotTag

Archive