0
votes

I have an issue within a complex project: Somehow, Vue re-renders all children at every change
We use vue 2.5.17 with typescrip, class components and decorators.
I created a new, clean component that is not at all tied to other logic within our project:

import { Component, Prop } from 'vue-property-decorator'
import Vue, { CreateElement } from 'vue'

@Component
class InnerElement extends Vue {

  @Prop({ required: true })
  value: number

  render (h: CreateElement) {
    console.log('render InnerElement: ' + this.value)
    return <div key={this.value}>Value: {this.value}</div>
  }
}

@Component
export class Outside extends Vue {

  list: number[]
  parentCounter: number

  constructor () {
    super()
    this.list = []
    this.parentCounter = 0
  }

  addElement () {
    this.list.push(this.list.length)
  }

  render (h: CreateElement) {
    console.log('render parent')
    return <div>
      <div>Outside component counter: {this.parentCounter}</div>
      <button onClick={() => {
        console.log('Increase counter')
        this.parentCounter++
      }}>Increase counter</button>
      <div>{this.list.map(item => <InnerElement value={item} />)}</div>
      <button onClick={this.addElement}>Add element</button>
    </div>
  }
}

Normally, when I would click on 'Increase counter', none of the InnerElement children should be re-rendered. When I add a new item into the list array, only the newly added element should be renderd.
I have tested this in a new, clean project and it works as expected. In the project where we have the problem, this is the behaviour: I add a new element, all the existing ones are re-rendered. I increase the counter, all the elements are re-rendered:

This is how it looks if I do the following flow: add 4 elements and in the end, increase the counter: enter image description here

This is the normal behavior, in a newly created project, for the exact same flow: enter image description here

The dummy project uses vue 2.6.11 and I didn't bothered with adding webpack-dev-server, vuex and maybe some other libraries because I don't think these should impact the way things are rendered.
I am totally out of ideas, I don't have the smallest clew of where to look, couldn't find anything on the internet so far.
Thank you!

I have zero experience wit JSX so I could be wrong but why do you have a key on the <div> inside InnerElement ? The key should be placed on the InnerElement when it is rendered in Outside component...Michal Levý
InnerElement returns the contend of render method, so, a <div> that already has the key set. InnerElement it's just a wrapper, the html resulted will be the same as if I would write it by hand, html element by html element. Beside this, in one case it works and in the other case it does not. @MichalLevýCiprian Iacob