Posted on

All you need to know about @track decorator in Lightning Web Component.

The Lightning Web Components programming model has three decorators that add functionality to a property or function.

  1. @track
  2. @api and
  3. @wire

In this blog we will learn about @track decorator in LWC.

In simple term, @track is a private reactive property. Here private reactive means that any changes in the data are atomically refreshing on the UI and not exposed to the other components.

@track is like a private method in your apex class which means you can only access @track in your local LWC file as these properties are strictly inside the component.

You can use a @track property directly in a template and indirectly in a getter of a property that’s used in a template.

From SPRING’20: The @track Decorator Is No Longer Required for Lightning Web Components.

Before Spring ’20, to make a field reactive, you had to decorate it with @track. Below is the example that we used in older code samples, and it’s still supported.

This component has one input field: message. When you write a message on the input field, the component updates the old message and displays the new message.

showMessage.html

<template>
   <div class="slds-p-around_small">
    <lightning-input type="text" value={message} onchange={handleChange}></lightning-input>
    <br/>  Message: {message}
   </div>
</template>

showMessage.js

import {LightningElement, track} from 'lwc';

export default class ShowMessage extends LightningElement {
    @track message = '@track in Lightning Web Component';

    handleChange(event) {
        this.message = event.target.value;
    }
}

Before Spring ’20, to rerender the component when a user writes a message, you had to decorate the fields with @track.

@track message = '@track in Lightning Web Component';
When user writes new message in lightning-input field

From Spring’20, All Primitive type fields in a Lightning Web Component are reactive by default. If a field’s value changes, and the field is used in a template or in a getter of a property that’s used in a template, the component rerenders and displays the new value.

Primitive data type fields: A primitive data value is a single simple data value with no additional properties and methods. Example: String, Number ,Boolean, undefined etc.

Let’s understand this with the help of same example as above:

This time we removed the @track from message field. Since message is a Primitive type field so it is reactive by default. Hence the component will rerender and displays the new value as shown in the above images.

showMessage.html

<template>
   <div class="slds-p-around_small">
    <lightning-input type="text" value={message} onchange={handleChange}></lightning-input>
    <br/> Message: {message}
   </div>
</template>

showMessage.js

import {LightningElement} from 'lwc';

export default class ShowMessage extends LightningElement {
    message = '@track in Lightning Web Component';

    handleChange(event) {
        this.message = event.target.value;
    }
}

The @track Decorator is still required for an Object’s Properties or an Array’s Elements.

There is still one use case for @track. When a field contains an object or an array, there’s a limit to the depth of changes that are tracked. To tell the framework to observe changes to the properties of an object or to the elements of an array, decorate the field with @track.

Now, only use the @track decorator if the field is an array or an object.

Without using @track, the framework observes changes that assign a new value to a field. If the new value is not equals to the previous value, the component rerenders.

Let’s understand this with an example.

Suppose we want to display both the default message and the new message so we will declare the message field as an object which contains two properties, defaultMessage and newMessage.

message ={defaultMessage:'' ,newMessage:''}

showMessage.html

<template>
  <div class="slds-p-around_small">
    <lightning-input type="text" value={message.defaultMessage} onchange={handleChange}></lightning-input>
     <br/> Default Message: {message.defaultMessage} 
     <br/> New Message: {message.newMessage} 
  </div>
</template>

The framework observes changes that assign a new value to message field. This code assigns a new value to the message field, so the component rerenders.

import { LightningElement } from 'lwc';

export default class ShowMessage extends LightningElement {
    message = { defaultMessage: '@track in Lightning web component', newMessage: '' }

    handleChange(event) { //Here component rerenders because we are assigning new value to the message field. 
        this.message = {
            defaultMessage: '@track in Lightning web component',
            newMessage: event.target.value
        }

        console.log(JSON.stringify(this.message));
    }
}
Default message
When user adds a new message in lightning-input field

If you try to assign a new value to any of the message property , you will see that newMessage value changes but the component doesn’t rerenders because  properties aren’t observed as it assigns a new value to the newMessage property of the message object.

handleChange(event)  { //Here newMessage value changes but Component doesn't rerender.
    this.message.newMessage= event.target.value;
    console.log(JSON.stringify(this.message.newMessage));
}
newMessage value changes but component doesn’t rerender.

To tell the framework to observe changes to the object’s properties, decorate the message field with @track. Now if we change newMessage property of the message object, the component rerenders.

import { LightningElement, track } from 'lwc';

export default class ShowMessage extends LightningElement {
    @track message = {
        defaultMessage: 'track in Lightning web component',
        newMessage: ''
    }

    handleChange(event) { //Here the component rerenders because message field is decorated with @track
        this.message.newMessage = event.target.value;
        console.log(JSON.stringify(this.message.newMessage));
    }
}
Here the component rerenders because message field is decorated with @track

Leave a Reply

Your email address will not be published. Required fields are marked *