最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to Fix Vue Warning: You may have an infinite update loop in a component render function - Stack Overflow

programmeradmin4浏览0评论

I am getting the following infinite loop warning. I understand that it is probably because I am changing a variable in my template's for loop due to a method call. Any idea how to fix it? The loop does plete, so it's not actually an infinite loop, but I'd like to fix the warning.

[Vue warn]: You may have an infinite update loop in a ponent render function.

Code Snippet:

new Vue({
  el: '#app',
  data: {
    contents: {"34": {"id": 34, build_name: "email_simple", build_readable: "Email"},"35": {"id": 35, build_name: "email_plex", build_readable: "Email"},"36": {"id": 36, build_name: "email_half", build_readable: "Email"}},
    last_build_type: '',
    contents_tree: [34,35,36]
  }, 
  methods: {
      checkBuildType(id){
        let check = false;
        if(this.last_build_type !== this.contents[id].build_name){
            check = true
        }
        this.last_build_type = this.contents[id].build_name;
        return check
      }

  }
  
})
<script src=".5.17/vue.js"></script>
<div id="app">
  <template v-for="(id, i) in contents_tree">
      <div v-bind:key="i + '_' + id" class="inline">
          <template v-if="checkBuildType(id)">
              {{i}} - {{id}} -
              {{contents[id].build_readable}}
              <br>
            
          </template>

    </div>
  </template>
</div>

I am getting the following infinite loop warning. I understand that it is probably because I am changing a variable in my template's for loop due to a method call. Any idea how to fix it? The loop does plete, so it's not actually an infinite loop, but I'd like to fix the warning.

[Vue warn]: You may have an infinite update loop in a ponent render function.

Code Snippet:

new Vue({
  el: '#app',
  data: {
    contents: {"34": {"id": 34, build_name: "email_simple", build_readable: "Email"},"35": {"id": 35, build_name: "email_plex", build_readable: "Email"},"36": {"id": 36, build_name: "email_half", build_readable: "Email"}},
    last_build_type: '',
    contents_tree: [34,35,36]
  }, 
  methods: {
      checkBuildType(id){
        let check = false;
        if(this.last_build_type !== this.contents[id].build_name){
            check = true
        }
        this.last_build_type = this.contents[id].build_name;
        return check
      }

  }
  
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <template v-for="(id, i) in contents_tree">
      <div v-bind:key="i + '_' + id" class="inline">
          <template v-if="checkBuildType(id)">
              {{i}} - {{id}} -
              {{contents[id].build_readable}}
              <br>
            
          </template>

    </div>
  </template>
</div>

Share edited Mar 25, 2020 at 15:25 AlexMA 10.2k7 gold badges45 silver badges66 bronze badges asked Mar 25, 2020 at 12:34 JordanJordan 1,6522 gold badges17 silver badges27 bronze badges 10
  • what is contents_tree? I believe we need more code to see what is actually causing the error – depperm Commented Mar 25, 2020 at 12:35
  • i think checkBuildType will alwayse returns true because new build would be different from current if i'm understanding your code correctly. – Harsh Srivastava Commented Mar 25, 2020 at 12:39
  • @depperm I have added an example contents_tree and an example contents. – Jordan Commented Mar 25, 2020 at 12:41
  • 1 Happy to help but please provide a runnable codepen or other plete snippet that reproduces the bug.stackoverflow./help/minimal-reproducible-example – AlexMA Commented Mar 25, 2020 at 12:53
  • 2 @AlexMA I have added the code snippet which is generating the error. – Jordan Commented Mar 25, 2020 at 13:16
 |  Show 5 more ments

1 Answer 1

Reset to default 4

You are getting that warning because Vue has to re-render for each item in the v-for loop, due to the fact that the for loop updates the ponent's state. My solution is to pute the result for each array item in one pass, in a puted property (basically an index object), and access that puted property in the v-for rather than using the checkBuildType method.

new Vue({
  el: '#app',
  data: {
    contents: {
      "33": {
        "id": 33,
        build_name: "email_half",
        build_readable: "Email"
      },
      "34": {
        "id": 34,
        build_name: "email_simple",
        build_readable: "Email"
      },
      "35": {
        "id": 35,
        build_name: "email_plex",
        build_readable: "Email"
      },
      "36": {
        "id": 36,
        build_name: "email_half",
        build_readable: "Email"
      },
      "37": {
        "id": 37,
        build_name: "email_half",
        build_readable: "Email"
      }
    },
    last_build_type: '',
    contents_tree: [34, 35, 36, 37, 33]
  },
  puted: {
    buildTypes() {
      const buildTypesMap = {};
      for (id of this.contents_tree) {
        buildTypesMap[id] = this.checkBuildType(id);
      }
      return buildTypesMap
    }
  },
  methods: {
    checkBuildType(id) {
      let check = false;
      if (this.last_build_type !== this.contents[id].build_name) {
        check = true
      }
      this.last_build_type = this.contents[id].build_name;
      return check
    }

  }

})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <template v-for="(id, i) in contents_tree">
      <div v-bind:key="i + '_' + id" class="inline">
          <template v-if="buildTypes[id]">
              {{i}} - {{id}} -
              {{contents[id].build_readable}}
              <br>
            
          </template>

</div>
</template>
</div>

发布评论

评论列表(0)

  1. 暂无评论