Lifecycle Hooks of Lightning Web Components:
Lightning web components have a lifecycle managed by the framework. The framework creates components, inserts them into the DOM, renders them, and removes them from the DOM. It also monitors components for property changes.
Typically the lifecycle includes following steps:
- Component construction phase
- Component DOM insertion phase
- Component rendering phase
- Component error handling phase
- Component DOM removal phase
To understand the lifecycle in more detail, let's have a look at the
following component structure which is based on Parent-Child relationship.
This example will help to understand the exact flow of lifecycle of parent
vs child.
By the end of this blog we will be able to understand
☞ Which component DOM is inserted first
☞ Different lifecycle hooks in Parent-Child modal and their execution
☞ Order in which they are removed from DOM.
☞ Different lifecycle hooks in Parent-Child modal and their execution
☞ Order in which they are removed from DOM.
Implementation:
Theory apart, let's design our components of interest.
-
Parent Component:
containerComponent.html
containerComponent.js<template> <lightning-card> <lightning-layout class="slds-var-m-around_medium"> <lightning-layout-item class="wide" style="width: 100%;"> <div class="slds-var-p-around_small"> <p>You're in container component.</p> <c-child text={text}></c-child> </div> </lightning-layout-item> </lightning-layout> </lightning-card> </template>
import { LightningElement } from 'lwc'; export default class ContainerComponent extends LightningElement { text = 'You\'re in child component.'; getChildElement() { let child = this.template.querySelector('c-child'); console.log('child element in main component: ' + child); } constructor() { super(); console.log('Constructor of main component is called.'); console.log('text value in main constructor: ' + this.text); this.getChildElement(); } connectedCallback() { console.log('ConnectedCallback of main component is called.'); console.log('text value in main connectedCallback: ' + this.text); this.getChildElement(); } renderedCallback() { console.log('RenderedCallback of main component is called.'); console.log('text value in main renderedCallback: ' + this.text); this.getChildElement(); } disconnectedCallback() { console.log('DisconnectedCallback of main component is called.'); console.log('text value in main disconnectedCallback: ' + this.text); this.getChildElement(); } errorCallback() { console.log('ErrorCallback of main component is called.'); console.log('text value in main errorCallback: ' + this.text); this.getChildElement(); } }
-
Child Component:
child.html
child.js<template> <div class="slds-box"> <span>{text}</span> </div> </template>
import { LightningElement, api } from 'lwc'; export default class Child extends LightningElement { @api text; constructor() { super(); console.log('Constructor of child component is called.'); console.log('text value in child constructor: ' + this.text); } connectedCallback() { console.log('ConnectedCallback of child component is called.'); console.log('text value in child connectedCallback: ' + this.text); } renderedCallback() { console.log('RenderedCallback of child component is called.'); console.log('text value in child renderedCallback: ' + this.text); } disconnectedCallback() { console.log('DisconnectedCallback of child component is called.'); console.log('text value in child disconnectedCallback: ' + this.text); } errorCallback() { console.log('ErrorCallback of child component is called.'); console.log('text value in child errorCallback: ' + this.text); } }
Observation:
Let's deploy our code sample to home page of our app in our
testing environment and look at the different phases of component
lifecycle of this Parent-Child modal.
-
Component construction phase: At this phase, the
constructor() method is fired as component instance is being created. Don’t
add attributes to the host element during construction. You can add
attributes to the host element in any other lifecycle hook.
This phase is from Parent to Child. Look at the result of
construction phase.
The flow starts from parent and until the parent is inserted in
the DOM, there is no child element created. Also the
construction phase doesn't allow to set up any attribute values
and hence we are getting the text value as null in child
component.
Construction Phase(Parent to Child)
-
Component DOM insertion phase: This is the second phase where
the
DOM insertion
happens. This phase is also from Parent to Child. At
this stage the connectedCallback() of Parent is fired ahead of
Child. Note that the
Child constructor() and connectedCallback() are fired
after Parent DOM insertion(connectedCallback). Also look at
the property text which is set after the
connectedCallback of Child and not in the
constructor of child. Also since the
child is still not rendered, the child element in main
component is still blank.
DOM Insertion(Parent to Child) -
Component rendering phase: This is the most interesting phase
of component lifecycle which is
rendering of components.
This time the
child is rendered first and then the parent is rendered. This
way, when the parent is rendered, you can now access the child
element in the lifecycle.
Rendering of Components(Child to Parent)
-
Component DOM removal phase: This is the phase where the
components start isolating from DOM and eventually go away. This
phase is started from Parent meaning the Parent is removed first and
then the child is removed.
DOM Removal(Parent to Child)
To put everything, we have been through so far, in a nutshell, below
describes the complete architecture of lightning web component's flow
of execution or lifecycle.
Lifecyle Hooks |
Cool, this completes the flow of lightning web components lifecycle
and hope you have aced it now in understanding of how the flow
starts and how it propagates. Stay tuned to more such amazing blogs
going ahead.
If you like this blog content and find inciteful, please comment and let me know.
I have a question.
ReplyDeleteyou used super function in parent/child constructor why we are using that. Is it necessary to use them and if yes whose constructor these are calling
Hello, that's very valid question and thanks for asking that.
DeleteThe answer to your first question is YES, we have to have this super function in the constructor of any LWC component if we are to use the constructor in that.
Now to answer your second question WHY- Firstly we need to understand the basics of Lightning Web Components which are built upon modern web stack. Whenever we create any LWC Component, they are termed as Lightning Custom Element similar to HTML Custom Element on web stack. If you see the very first line in JS Class that extends the LightningElement, basically this is built on extending the HTMLElement which are custom element and calling constructor() of any custom element requires the super() constructor to be called for web stack with no parameters. This call establishes the correct prototype chain and value for "this". Always call super() before touching "this".
You can refer to below links for more details:
https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.create_lifecycle_hooks_created
Hope you should be clear with your question now.
It's really helpful. Example is so explanatory and flow is very understandable.
ReplyDeleteReally very nice content and helpful to understand concept of Lwc HookLifeCycle
ReplyDelete