LWC Decorators @api, @track, @wire
Learn about the 3 LWC Decorators — @api, @track, and @wire — and how they help you build powerful, reactive, and data-driven Lightning Web Components.
1. Introduction
In Salesforce Lightning Web Components (LWC), you can retrieve data from Salesforce without writing custom Apex classes or methods. LWC provides various methods for fetching data declaratively and efficiently.
We'll explore several ways to retrieve data without using Apex, using Wire Adapters. By using these, we can improve performance with efficient data caching and eliminate the need for Apex.
LWC provides 3 decorators to manage component data and communication:
• @api — Expose properties and methods to parent components.
• @track — Track changes in complex objects and arrays.
• @wire — Fetch data from Salesforce declaratively.
2. @api Decorator
The @api decorator exposes properties and methods to the parent component. This allows the parent component to interact with or change the value of the child component's properties or invoke its methods.
The @api decorator in LWC is essential for creating reusable and configurable components.
Child Component (childComponent.js):
import { LightningElement, api } from 'lwc';
export default class ChildComponent extends LightningElement {
// Exposing a property to be set by the parent
@api greeting = 'Hello from Child!';
// Exposing a method to be called by the parent
@api
changeGreeting(newGreeting) {
this.greeting = newGreeting;
}
}
Parent Component (parentComponent.js):
import { LightningElement } from 'lwc';
export default class ParentComponent extends LightningElement {
// This property will be passed to the child component
greetingMessage = 'Hi from Parent!';
// You can call methods of the child using `template.querySelector`
changeChildGreeting() {
const child = this.template.querySelector('c-child-component');
child.changeGreeting('New Greeting from Parent!');
}
}
Parent Component HTML (parentComponent.html):
<!--parentComponent.html -->
<template>
<c-child-component greeting={greetingMessage}></c-child-component>
<lightning-button label="Change Greeting" onclick={changeChildGreeting}></lightning-button>
</template>
• The @api decorator is used to expose the greeting property and the changeGreeting method from the child to the parent.
• The parent can bind to the greeting property and update it when needed, or call the changeGreeting method to change the greeting in the child.
3. @track Decorator
The @track decorator was used to make properties reactive in earlier versions of LWC. However, in the latest LWC versions, @track is not required for primitive data types.
But if you want to track complex nested objects or arrays explicitly, @track can still be useful. When a tracked property is modified, the component automatically re-renders to display the updated value.
import { LightningElement, track } from 'lwc';
export default class ExampleComponent extends LightningElement {
@track contact = {
Name: 'John Doe',
Title: 'CEO'
};
updateContact() {
this.contact.Title = 'President'; // This change will be tracked
}
}
• Without @track, updating this.contact.Title would not trigger a re-render because LWC doesn't detect nested object changes by default.
• With @track, LWC watches the object deeply and re-renders when any nested property changes.
• For simple primitives (String, Number, Boolean), @track is not needed — LWC tracks them automatically.
4. @wire Decorator
The @wire decorator in Lightning Web Components (LWC) is a powerful mechanism for efficiently retrieving data from Apex methods or a wire adapter (like getRecord or getObjectInfo).
It handles the asynchronous nature of data fetching, making your code cleaner and easier to manage.
JavaScript Controller (myComponent.js):
import { LightningElement, wire } from 'lwc';
import getAccountList from '@salesforce/apex/AccountController.getAccountList';
export default class MyComponent extends LightningElement {
@wire(getAccountList) accounts;
get accountNames() {
return this.accounts.data ? this.accounts.data.map(account => account.Name) : [];
}
}
HTML Template (myComponent.html):
<!-- myComponent.html -->
<template>
<ul>
<template for:each={accountNames} for:item="accountName">
<li key={accountName}>{accountName}</li>
</template>
</ul>
</template>
• The @wire decorator binds the getAccountList Apex method to the accounts property.
• Whenever the data is returned (or if it changes), the component will automatically re-render with the new account names.
• The accounts property has two sub-properties: accounts.data (the result) and accounts.error (any error).
5. Decorator Comparison
@api:
• Makes a property or method public — accessible from the parent component.
• Used for parent-to-child communication.
• Example: passing a value from parent to child, or calling a child method from the parent.
@track:
• Makes a property deeply reactive — watches nested object/array changes.
• Not needed for primitive values (automatically reactive in modern LWC).
• Use when working with Objects or Arrays that have nested properties.
@wire:
• Declaratively fetches data from Salesforce — Apex methods or built-in wire adapters.
• Automatically handles async data fetching and caching.
• Returns an object with .data and .error properties.
• Component re-renders automatically when wired data changes.
