#3: Component Lifecycle & Compositions | Learn Lightning Web Component Development | LWC Stack Salesforce



Agenda

 The agenda of this blog will be to learn more about Lightning Web Components lifecycle hooks and Composition, and how you can use them.

  • constructor()
  • connectedCallback()
  • disconnectedCallback()
  • renderedCallback()
  • errorCallback()
  • LWC Composition

Where to use lifecycle hooks?

constructor() :- The constructor() fires when a component instance is created. 
connectedCallback() :- Fires when a component is inserted into the DOM.
disconnectedCallback() :- Fires when a component is removed from the DOM.
renderedCallback() :- Fires when a component is rendered on the DOM.
errorCallback() :- Fires in case of any error during a lifecycle hook or event.


When a web page is loaded, the browser creates a Document Object Model of the page. The HTML DOM model is constructed as a tree of Objects
The Document Object Model (DOM) is a programming interface for web documents. It represents the page so that programs can change the document structure, style, and content.

It basically creates a tree of Objects like first there should be root element then head,body and other elements and then you may have some text, images or custom CSS. 


This diagram is talking about one parent and one child component.
  1. Constructor is called
  2. Public property are set on parent
  3. Parent is inserted to DOM
  4. Once parent is inserted to DOM, Connected callback is called on parent
  5. From this connected callback as parent is already inserted, you can reference different DOM elements
  6. Parent is rendered
  7. Once parent is rendered, Constructor is called on the child
  8. Public property of child are set
  9. Child is inserted to DOM
  10. Once child is inserted to DOM, Connected callback is called on child
  11. Child is rendered
  12. Once child is rendered, rendered callback is called
  13. Once child components are rendered on the screen, then parents rendered callback is called.
Now let’s dig a little deep in it and see their capabilities !


constructor()

  • The constructor() method fires when a component instance is created. Don’t add attributes to the host element during construction.
  • The first statement must be super() with no parameters. This call establishes the correct prototype chain and value for this. Always call super() before touching this.
  • It flows from parent to child.
  • Don’t inspect the element's attributes and children, because they don’t exist yet.
  • Don’t inspect the element’s public properties, because they’re set after the component is created.
  • Do not assign any property in Constructor because they are not ready at this point.
The flow of Constructor is flows from parent to child. It means if there are child components in LWC, then first parent constructor will be called, followed by child constructor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { LightningElement } from "lwc";

export default class LifecycleHooks extends LightningElement {
  constructor() {
    super();
    console.log("Constructor");
  }
}

// Output: Constructor


connectedCallback() & disconnectedCallback()

  • Both hooks flow from parent to child.
  • You can’t access child elements from the callbacks because they don’t exist yet.
  • To access the host element, use this. To access elements in a component’s template, use this.template.
  • Use connectedCallback() to interact with a component's environment. For example, use it to:
  • Establish communication with the current document or container and coordinate behavior with the environment.
  • Perform initialization tasks, such as fetch data, set up caches, or listen for events
  • Subscribe and Unsubscribe from a Message Channel.
  • Use disconnectedCallback() to clean up work done in the connectedCallback(), like deleting caches or removing event listeners.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import { LightningElement } from "lwc";

export default class LifecycleHooks extends LightningElement {
  myList = [];
  constructor() {
    super();
    console.log("Constructor");
  }
  connectedCallback() {
    this.myList.push("Salesforce Bolt");
    console.log("ConnectedCallBack");
  }
  disconnectedCallback() {
    this.myList = [];
    console.log("disconnectedCallBack");
  }
}

//Output
//Constructor
//ConnectedCallBack


renderedCallback()

  • Run code when a component renders.
  • Use it to perform logic after a component has finished the rendering phase.
  • This hook flows from child to parent.
  • A component is usually rendered many times during the lifespan of an application. To use this hook to perform a one-time operation, use a boolean field 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.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { LightningElement } from "lwc";

export default class LifecycleHooks extends LightningElement {
  myList = [];
  constructor() {
    super();
    console.log("Constructor");
  }
  connectedCallback() {
    this.myList.push("Salesforce Bolt");
    console.log("ConnectedCallBack");
  }
  disconnectedCallback() {
    this.myList = [];
    console.log("disconnectedCallBack");
  }
  renderedCallback() {
    console.log("renderCallBack");
  }
}

//Output
//Constructor
//ConnectedCallBack
//RenderCallBack


errorCallback()

  • Implement it to create an error boundary component that captures errors in all the related components in its tree.
  • Captures lifecycle hooks or during an event handler declared in an HTML template. 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { LightningElement } from "lwc";

export default class LifecycleHooks extends LightningElement {
  myList = [];
  constructor() {
    super();
    console.log("Constructor");
  }
  connectedCallback() {
    this.myList.push("Salesforce Bolt");
    console.log("ConnectedCallBack");
  }
  disconnectedCallback() {
    this.myList = [];
    console.log("disconnectedCallBack");
  }
  renderedCallback() {
    console.log("renderCallBack");
  }
  errorCallback(error, stack) {
    console.log("ErrorCallBack: " + error);
  }
}

//Output
//Constructor
//ConnectedCallBack
//RenderCallBack


LWC Composition

In LWC you can create/compose a component with a set of smaller components to make to code more reusable and easy to maintain. 

Let's look at below example to learn how you can compose a component as child in a parent component.
1
2
3
4
5
6
7
8
<template>
    <lightning-card title="I am Parent" icon-name="utility:user">
        <div class="slds-var-m-around_medium">
            <c-child-Component-Basic>
            </c-child-Component-Basic>
        </div>
    </lightning-card>
</template>


In this example we have composed a LWC with a child component 
"c-child-component-basic"

Few things to remember here:
  • Owner: The owner is the component that owns the template. In this example, the owner is the c-child-component-basic component. The owner controls all the composed components that it contains. The owner can:
    • Set public properties on composed components
    • Call methods on composed components
    • Listen for any events fired by the composed components
  • Container: A container contains other components but itself is contained within the owner component. In this example, Parent is a container. A container is less powerful than the owner. A container can:
    • Read, but not change, public properties in contained components
    • Call methods on composed components
    • Listen for some, but not necessarily all, events bubbled up by components that it contains.
  • Parent and child: When a component contains another component, which, in turn, can contain other components, we have a containment hierarchy. In the documentation, we sometimes talk about parent and child components. A parent component contains a child component. A parent component can be the owner or a container.

Checkout the Crash Course Below

 If you have any question please leave a comment below.

If you would like to add something to this post please leave a comment below.
Share this blog with your friends if you find it helpful somehow !

Thanks
Happy Coding :)

Post a Comment

0 Comments