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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.