@track Decorator in LWC
Learn how the @track decorator works in Lightning Web Components — when you need it, when you don't, and how to handle reactive Objects and Arrays.
1. Introduction
Lightning Web Components (LWC) is a modern framework for building web components on the Salesforce platform. One of the core concepts in LWC is reactive properties, which enable automatic data synchronization between a component's JavaScript logic and its user interface (UI) elements.
The @track decorator is a key tool for making properties reactive.
Starting from Spring '20, LWC no longer requires the @track decorator for fields to be reactive. This simplifies the development process by automatically tracking changes to any field in a component class.
2. Before Spring '20
Before this update, you had to use @track to make fields reactive. Without it, changes to a field would not trigger a re-render of the component.
import { LightningElement, track } from 'lwc';
export default class TrackExampleCmd extends LightningElement {
@track firstName = 'Satyam';
@track lastName = 'Parasa';
}
3. After Spring '20
With the Spring '20 update, you no longer need to use @track for primitive fields, and it works as expected. All fields in a component class are now reactive by default.
import { LightningElement } from 'lwc';
export default class TrackExampleCmd extends LightningElement {
firstName = 'Satyam';
lastName = 'Parasa';
}
• Both examples above will re-render the UI when firstName or lastName is updated.
• The second example (without @track) is the recommended modern approach for primitive values.
4. Handling Objects and Arrays
While all fields are reactive by default, if you're working with objects or arrays, you may still need to use @track. The reason is that changes to nested properties or array elements are not tracked by default.
When you assign a new object to a field, the component rerenders:
this.fullName = { firstName: 'Satyam', lastName: 'Parasa' };
But if you change a property of the object directly, like this.fullName.firstName = 'Sathyam', the component will not rerender unless you decorate the field with @track.
5. Example — Using @track with Objects
To handle nested property changes, decorate the object field with @track:
import { LightningElement, track } from 'lwc';
export default class ReactivePropertyExample extends LightningElement {
@track fullName = { firstName: 'Satyam', lastName: 'Parasa' };
updateFirstName() {
this.fullName.firstName = 'Sathyam'; // This triggers a rerender.
}
}
<template>
<lightning-card title="Track example" icon-name="utility:sync">
<div class="slds-m-around_medium">
{fullName.firstName}
</div>
<lightning-button variant="brand-outline"
label="Update first Name"
onclick={updateFirstName}
class="slds-m-left_x-small">
</lightning-button>
</lightning-card>
</template>
• With @track on fullName, changing this.fullName.firstName will trigger a re-render.
• Without @track, the UI would show Satyam even after clicking the button — because LWC doesn't detect the nested change.
• After clicking "Update first Name", the UI updates to display Sathyam.
6. Summary
No need for @track on simple fields:
Any field that directly holds a value and is used in the template or a computed property (getter) will automatically trigger a rerender when its value changes. No @track needed for primitives like String, Number, Boolean.
Use @track only for complex fields:
When dealing with objects or arrays, @track is still necessary to observe changes to nested properties or array elements. Without @track, only reassigning the entire object/array triggers a re-render.
📝 Quick Rule:
• this.name = 'New Name' → re-renders automatically (no @track needed).
• this.user.name = 'New Name' → needs @track on user to re-render.
• this.items.push(newItem) → needs @track on items to re-render.
