renderedCallback() in Lightning Web Component

A lifecycle hook is a callback method triggered at a specific phase of a component instance’s lifecycle. One of them is renderedCallback() in Lightning Web Component. The renderedCallback() is unique to Lightning Web Components. Use it to perform logic after a component has finished the rendering phase.

This hook flows from child to parent. In simple words, if you are dealing with nested parent child component, renderedCallback() method in child component will get fired first.

What you can do within in a renderedCallback() in Lightning Web Component ?

It is very important to know the everything about renderedCallback() method in Lightning Web Component like best practices, considerations and limitations. Let’s create a simple Lightning Web Component with name renderedCallbackInLWC. All lightning web Components has three files in its folder structure by default.

What you can do within in a  renderedCallback() in Lightning Web Component ?

Let’s start with basic syntax of writing renderedCallback() method in Lightning Web Component.

import { LightningElement } from 'lwc';

export default class RenderedCallbackInLWC extends LightningElement {
    //basic syntax of renderedCallback method in Lightning Web Component
    renderedCallback() {
        //do something
    }
}

Question 1 – Can we set the properties in renderedCallback () in Lightning Web Component ?

Yes, You can set the properties in renderedCallback but best practise is do not use renderedCallback() to change the state of a component, such as loading values or setting properties. Use getters and setters instead.

The below example demonstrate why you should not use the renderedCallback() to set the properties.

renderedCallbackInLWC.html

<template>
    {properties}
    <lightning-button label="changePropertiesValues" onclick={handleButtonClick}></lightning-button>
</template>

renderedCallbackInLWC.js

import { LightningElement, track } from 'lwc';

export default class RenderedCallbackInLWC extends LightningElement {
    @track properties;
    renderedCallback() {
        this.properties = 'set by renderedCallback';
        console.log('properties ' + this.properties);
    }

    handleButtonClick() {
        this.properties = 'set by buttonClick';
    }
}

If you place the above component in your lightning page and check the console log, you will find that renderedCallback() gets fired multiple times.

renderedCallback() in Lightning Web Component

Even after clicking on button which actually changing the value of the property using handleButtonClick() method, the value does not gets changed because it gets reset when renderedCallback() gets called.

Can we set the properties in renderedCallback () in Lightning Web Component ?

To you use this hook to perform a one-time operation, use a private boolean property like hasRendered to track whether renderedCallback() has been executed. The first time renderedCallback() executes, perform the one-time operation and set hasRendered = true. If hasRendered = true, don’t perform the operation. See the below example:-

import { LightningElement, track } from 'lwc';

export default class RenderedCallbackInLWC extends LightningElement {
    @track properties;
    @track hasRendered = true;
    renderedCallback() {
        //guarding code inside the renderedCallback using boolean property
        if (hasRendered) {
            this.properties = 'set by renderedCallback';
            console.log('properties ' + this.properties);
            hasRendered = false;
        }
    }

    handleButtonClick() {
        this.properties = 'set by buttonClick';
    }
}

Question 2 – Can we Access elements the component owns inside the renderedCallback() method in Lightning Web Component?

Yes, You can access the elements owned by component but again you need to guard your code inside the renderedCallback() to prevent getting fired more than once if required. See the below example:-

<template>
    {properties}
    <lightning-button label="changePropertiesValues"></lightning-button>
</template>
import { LightningElement, track } from 'lwc';

export default class RenderedCallbackInLWC extends LightningElement {
    @track properties = 'defaulted when component loads';
    renderedCallback() {
        var button = this.template.querySelector('lightning-button');
        console.log(button.label);
    }
}

Question 3 – Can we call an apex method inside the renderedCallback() method in Lightning Web Component?

Yes, We can call a apex method inside the renderedCallback () in Lightning Web Component. Example:-

<template>
    <template if:true={contacts}>
        <template for:each={contacts} for:item="contact">
            <p key={contact.Id}>{contact.Name}</p>
        </template>
    </template>
</template>
import { LightningElement, track } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';

export default class RenderedCallbackInLWC extends LightningElement {
    @track contacts;
    @track error;

    renderedCallback() {
        getContactList()
            .then(result => {
                console.log('result - ' + result);
                this.contacts = result;
                this.error = undefined;
            })
            .catch(error => {
                console.log('error - ' + error);
                this.error = error;
                this.contacts = undefined;
            });
    }
}
Can we call an apex method inside the renderedCallback() method in Lightning Web Component?

Note:- Above console log says renderedCallback() method gets fired twice. Be cautious while calling an apex method via renderedCallback(). It is not a best practise to call from it. Guard your code inside it properly to fire more than once.

Question 4 – Can we create and dispatch events in renderedCallback() method of Lightning Web Component?

Yes, You can create and dispatch in renderedCallback() method. Be cautious while doing so because it method itself fired whenever component states changes or component renders. Guard your code inside the renderedCallback() properly to prevent it firing multiple times.

import { LightningElement, track } from 'lwc';

export default class RenderedCallbackInLWC extends LightningElement {
    @track contacts;
    @track error;

    renderedCallback() {
        // Creates the event with the contact ID data.
        const selectedEvent = new CustomEvent('renderedcallbackeventfired', { detail: this.contacts });

        // Dispatches the event.
        this.dispatchEvent(selectedEvent);
    }
}

Question 5 – Can we call the UI Api from renderedCallback() in Lightning web component?

Yes, UI Api call is supported inside the renderedCallback(). o you use this hook to perform a one-time operation, use a private boolean property like hasRendered to track whether renderedCallback() has been executed. The first time renderedCallback() executes, perform the one-time operation and set hasRendered = true. If hasRendered = true, don’t perform the operation. Let’s see the below example to create a record of account object:

import { LightningElement } from 'lwc';
import { createRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';

export default class RenderedCallbackInLWC extends LightningElement {

    renderedCallback() {
        const fields = {};
        fields[NAME_FIELD.fieldApiName] = 'account created from renderedCallback today';
        const recordInput = { apiName: ACCOUNT_OBJECT.objectApiName, fields };
        createRecord(recordInput)
            .then(account => {
                console.log('account.id;' + account.id);
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success',
                        message: 'Account created',
                        variant: 'success',
                    }),
                );
            })
            .catch(error => {
                console.log(JSON.stringify(error));
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error creating record',
                        message: error.body.message,
                        variant: 'error',
                    }),
                );
            });
    }
}

Note: Above example also proved the ability to fire a showToastEvent from renderedCallback() method.

Question 6 – Can we use navigation service inside the renderedCallback() in Lightning Web Component?

Yes, Navigation service will work fine when it is being used inside connectedCallback() method. To use this hook to perform a one-time operation, use a private boolean property like hasRendered to track whether renderedCallback() has been executed. The first time renderedCallback() executes, perform the one-time operation and set hasRendered = true. If hasRendered = true, don’t perform the operation. See the below example to navigate to a file:

import { LightningElement } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class RenderedCallbackInLWC extends NavigationMixin(LightningElement) {

    renderedCallback() {
        this[NavigationMixin.Navigate]({
            type: 'standard__namedPage',
            attributes: {
                pageName: 'filePreview'
            },
            state: {
                recordIds: '069B0000003M8wlIAC',
                selectedRecordId: '069B0000003M8wlIAC'
            }
        });
    }
}

Best Practises in renderedCallback()

We don’t recommend using renderedCallback() with @wire and @track in the following conditions, which result in an infinite loop.

  • renderedCallback() updates an @wire config change and the @wire provisioning triggers a render.
  • renderedCallback() updates an @track property, which triggers a render.

Use renderedCallback() to interact with a component’s UI. For example, use it to:

  • Compute node sizing
  • Perform tasks not covered by our template declarative syntax, such as add a listener for a non-standard event from a component’s child

The renderedCallback() lifecycle hook is often paired with connectedCallback(). Use renderedCallback() to understand the state of the “inside” world (a component’s UI and property state), and use connectedCallback() to understand the state of the “outside” world (a component’s containing environment).

References

One comment

  1. Hi great guide.
    vary informative and action specific content.i read each and Everypoint in this article thank you.

Leave a Reply