Two-Way Data Binding (@track)
Two-way data binding in LWC will help users to exchange data from the controller to the template and form template to the controller. It will help users to establish communication bi-directionally.
note - Before Spring ’20, to make a field reactive, you had to decorate it with @track. You see this approach used in older code samples, and it’s still supported.
How to achieve Two-Way Data Binding?
- The Lightning Web Components programming model has given us some decorators that add functionality to property or function.
- @track is the decorator that helps us to track a private property's value and re-render a component when it changes.
- Tracked properties are also called private reactive properties.
@trackhelps us to achieve two-way data binding
@trackis powerful, but remember, track a property only if you want the component to re-render when the property's value changes. Don't track every private property.
Example of Two-Way Data Binding
- In VS Code, open the Command Palette by pressing
Ctrl+Shift+Pon Windows orCmd+Shift+Pon macOS. - Type
SFDXand SelectSFDX: Create Lightning Web Component. - Type
twoWayDataBindingas the name of the new component and pressEnter. - Again, Press
Enterto accept the defaultforce-app/main/default/lwc. - Goto your
lwcfolder, you will see one new component with the nametwoWayDataBindinggets created. - Let's add the following code to
twoWayDataBinding.html,twoWayDataBinding.jsandtwoWayDataBinding.js-meta.xml
<template>
<lightning-card title="Two-way Data Binding Demo" icon-name="custom:custom2">
<hr />
<!--First input box-->
<div class="slds-p-around_medium">
<lightning-input
type="text"
name="fullname"
label="Enter your name:"
onkeyup={changeHandler}
value={fullname}
></lightning-input>
</div>
<!--Second input box-->
<div class="slds-p-around_medium">
<lightning-input
type="text"
name="title"
label="Enter your title:"
onkeyup={changeHandler}
value={title}
></lightning-input>
</div>
<!--Result of binding-->
<div class="slds-p-around_medium">
<h5>My name is {fullname} and my title is {title}</h5>
</div>
</lightning-card>
</template>- we have created two input box
fullnameandtitleusinglightning-inputinside thelightning-card. {name}- is used to bindfullnameproperty tofullnameinput box{title}- is used to bindtitleproperty totitleinput box- we have defined an event handler called
onKeyUpthat is bind tochangeHandler, which gets triggered on every key up. - We have used the
<h5>tag to test the two-way data binding
import { LightningElement, track } from "lwc";
export default class TwoWayDataBinding extends LightningElement {
@track fullname = "Salesforce Troop";
@track title = "Salesforce developer";
changeHandler(event) {
this[event.target.name] = event.target.value;
}
}- In the first line, we are importing
LightningElementandtrackfromlwcmodule - After that, we are creating a
classTwoWayDataBinding(Note - the class name always be pascal case) - Within the
class, we have to define two propertiesfullnameandtitle. @trackdecorator decorates both properties.- Both properties are assigned with an initial value of
Salesforce TroopandSalesforce developer, respectively. - We have defined a method
changeHandlerthat takes the value from the textbox and update the property based on the input box name
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="twoWayDataBinding">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>dataBinding.js-meta.xmlis a configuration file- The configuration file defines the metadata values for the component, including the design configuration for Lightning App Builder and Experience Builder.
Final Output
After placing the component on the page, you will see the following output.

note - Before Spring ’20, to make the component rerender when a user entered a first or last name, you had to decorate the fields with @track.
Observe 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.
Without using @track, the framework observes changes that assign a new value to a field. If the new value is not === to the previous value, the component rerenders.
To understand, let’s declare the fullName field, which contains an object with two properties, firstName and lastName.
fullName = { firstName : '', lastName : '' };The framework observes changes that assign a new value to fullName. This code assigns a new value to the fullName field, so the component rerenders.
// Component rerenders.
this.fullName = { firstName : 'Mark', lastName : 'Doe' };However, if we assign a new value to one of the object’s properties, the component doesn't rerender because the properties aren’t observed.
// Component doesn't rerender.
this.fullName.firstName = 'Mark';The framework observes changes that assign a new value to the fullName field. This code doesn't do that, instead it assigns a new value to the firstName property of the fullName object.
To tell the framework to observe changes to the object's properties, decorate the fullName field with @track. Now if we change either property, the component rerenders.
// Component rerenders.
@track fullName = { firstName : '', lastName : '' };
this.fullName.firstName = 'Mark';