About Me

My photo
PLANO, Texas, United States

Monday, November 9, 2020

Reactivity in LWC

In your real life, when and how you should react, it really matters. Similarly, when you write the LWC, you should know when the component should react or when it should not react. Sometimes, the LWC framework reacts automatically however, sometimes we need to tell the framework to react.

If a property is altered or changed, our component reacts and re-renders. You can choose if you want your component to react to a property change. If you don’t want then the component won't re-render.


In LWC, there are three types of decorators (A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter.) which can help to decide component reactivity.

  1. @track- private reactive property

  2. @api- public reactive properly 

  3. @wire-reactive service for data

Let's take a look in detail at each decorator.

@track

All primitive fields are reactive. 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 re-renders, and displays the new value.

Let’s take a very simple example where you input a number and get the square root. In the below example, intNumber is a reactive field as it is used in the getter method.  When I change the input, the square root updates automatically.

squrerootEx.html 


<template>

   <lightning-card title="Square root" icon-name="custom:custom113">

       <div class="slds-m-around_medium">

           <lightning-input type="number"

                            label="Enter Number"

                            value={intNumber}

                            onchange={getsequreroot}></lightning-input>

 

       <p class="slds-var-m-top_medium">

           Square root of {intNumber} is : {result}

       </p>

       </div>

      

   </lightning-card>

</template>


squrerootEx.js


import { LightningElement } from 'lwc';

 

export default class SumEx extends LightningElement {

  intNumber=1;

   getsequreroot(event){

       this.intNumber = event.target.value

   }

   get result(){

       let sqR = Math.sqrt(this.intNumber);

       return sqR;

    }

}


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

@track intNumber;


Only primitive fields are reactive. Object and array type fields are only reactive when you completely set the Object{} or array.


car = {name : '', color: ''}

this.car = {name: 'civic', color: 'blue'}

//component re-renders because the entire object is set again

this.car.name= 'figo'

//component doesn't re-renders because only a property under object is set


To make the component react to properties under an object{} or array, we have to use track 


@track car = {name : '', color: ''}

this.car.name = 'figo'

//component re-renders because we used track

@api

Property in LWC is private by default. To expose a public property, decorate a field with @api. Public properties define the API for a component.

To expose a public method, decorate it with @api. Public methods are part of a component’s API. To communicate down the containment hierarchy, owner and parent components can call JavaScript methods on child components.


Let’s create the two components, first one is a child where we define a property which we want to call it from the parent so we declare as @api as it can be exposed publicly.


childEx.html


<template>

   <div>{itemName}</div>

</template>


childEx.js

import { LightningElement,api } from 'lwc';

 

export default class ChildEx1 extends LightningElement {

   @api itemName;

}


parentEx.html

<template>

   <c-child-ex1 item-name="Milk"></c-child-ex1>

   <c-child-ex1 item-name="Bread"></c-child-ex1>

</template>


parentEx.js

import { LightningElement } from 'lwc';

 

export default class ParentEx1 extends LightningElement {}


In the above example, if you will not write itemName as @api, nothing will be exposed to the parent component.

@wire

wire is literally like a wire which connects LWC with salesforce Data. To read Salesforce data, Lightning web components use a reactive wire service. When the wire service provisions data, the component re-renders. Components use @wire in their JavaScript class to specify a wire adapter or an Apex method.


You can refer to my previous article to understand wire adapters.



Reference

Salesforce Documentation


No comments:

Post a Comment