0

Going through the LWC documentation for track decorator, I see this part:

When manipulating complex types like objects and arrays, you must create a new object and assign it to the field for the change to be detected.

To avoid such issues when working with complex objects, use the @track decorator to deeply tracks mutations made to the field value

I did a little test with the following component without using the @track decorator:

View

<template>
    <lightning-card  title="Re-rendering test">
        <div class="slds-m-around_medium">
        <h2 class="slds-text-heading_medium">
            <div>Variable value: {variable}</div>
            <div>Object property value: {object.name}</div>
        </h2>
        <div class="slds-p-around_medium lgc-bg" >
            <lightning-input type="text" label="Enter some text" onkeyup={handleKey}></lightning-input>
        </div>
        </div>
    </lightning-card>
</template>

Controller

import {LightningElement} from 'lwc';

export default class RenderTest extends LightningElement {

    variable = 10;
    object = {
        name: 'John'
    }
    handleKey(event){
        this.variable = event.target.value;
        this.object.name = event.target.value;
    }
}

Component after initial render Component After Render

I expected the object variable not to re-render in the view after I modified the input. However, my component re-renders perfectly fine after modifying the input:

enter image description here

So what exactly happened here? Did the whole Lightning Card re-render because one of the variables was of a primitive type? And if so, how does this happen - does the whole Template re-render, or only some of its subcomponents?

1 Answer 1

0

I managed to figure it out. The primitive type variables make the whole component re-render. It does not matter the tag, it re-renders the whole thing.

While objects properties or array values might not cause the component to re-render, if you change a value of both the object/array and some primitive type variable referenced in the template of the component, the whole component re-renders, and the newest value is displayed also for the object properties and arrays. See the following code and test as you will:

<template>
<lightning-card  title="Re-rendering test">
    <div class="slds-m-around_medium">
    <h2 class="slds-text-heading_medium">
        <div>Variable value: {variable}</div>
        <div>Object property value: {object.name}</div>
    </h2>
    <div class="slds-p-around_medium lgc-bg" >
        <lightning-input type="text" label="Enter some text" onkeyup={handleKey1}></lightning-input>
    </div>
    </div>
</lightning-card>
<lightning-card  title="Re-rendering test">
    <div class="slds-m-around_medium">
    <h2 class="slds-text-heading_medium">
        <div>Variable value: {variable}</div>
    </h2>
    <div class="slds-p-around_medium lgc-bg" >
        <lightning-input type="text" label="Enter some text" onkeyup={handleKey2}></lightning-input>
    </div>
    </div>
</lightning-card>
<lightning-card  title="Re-rendering test">
    <div class="slds-m-around_medium">
    <h2 class="slds-text-heading_medium">
        <div>Object property value: {object.name}</div>
    </h2>
    <div class="slds-p-around_medium lgc-bg" >
        <lightning-input type="text" label="Enter some text" onkeyup={handleKey3}></lightning-input>
    </div>
    </div>
</lightning-card>
import {LightningElement} from 'lwc';

export default class RenderTest extends LightningElement {
    variable = 10;
    object = {
        name: 'John'
    }
    handleKey1(event){ // will re-render the whole component since variable is a primitive type which is tracked by default
        this.variable = event.target.value;
        this.object.name = event.target.value;
    }
    handleKey2(event){ // will re-render the whole component since variable is a primitive type which is tracked by default
        this.variable = event.target.value;
    }
    handleKey3(event){ // will not re-render the whole component since object is a complex type which is not tracked by default
        this.object.name = event.target.value;
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .