[SalesForce] Why do we need to destroy lightning components

I was looking at this blog post about Dynamically Instantiate and destroy Lightning Components – Modal dialog component and author is instantiating, destroying child component from the code.

But I was able to replicate similar output without doing all(instantiating and destroying from code) of that so curious about the whole concept of destroying components programmatically.

  1. Why do we need to destroy lightning components from the code?
  2. Don't lightning components get destroyed when user navigates to
    different url/page?
  3. I think destroying components is something similar to garbage collection in java but besides performance improvements or there are any functional bugs in my implementation below:

ExampleOne.app:

<aura:attribute name="input1" type="String"/>
<aura:attribute name="input2" type="String"/>

<div aura:id="parent-div-id">

    <div class="slds-form-element slds-size--1-of-6 slds-m-around--xx-small">
        <ui:inputText label="param 1" value="{!v.input1}"  class="slds-input"/>
    </div>
    <div class="slds-form-element slds-size--1-of-6 slds-m-around--xx-small">
        <ui:inputText label="param 2" value="{!v.input2}"  class="slds-input"/>
    </div>

    <div class="slds-size--1-of-6 slds-m-around--xx-large slds-clearfix">
        <ui:button label="Open Modal Dialog" 
                    press="{!c.openModal}" 
                    class="slds-button slds-button--destructive slds-float--right"  />
    </div>

    <!-- Modal for editing schedules -->
    <div role="dialog" id="child-modal" tabindex="-1" aria-labelledby="header44" class="slds-modal">
        <div class="slds-modal__container">
            <div class="slds-modal__content slds-p-around--medium">
                <div class="slds-form-element">
                    <c:ModalComponent aura:id="childCmp"/>
                </div>
            </div>
            <div class="slds-modal__footer">
                <button class="slds-button slds-button--neutral" onclick="{!c.closeModal}">Cancel</button>
            </div>
        </div>            
    </div>        

    <div id="modal-backdrop" class="slds-backdrop"></div>
</div>               

ExampleOneController.js:

({
    openModal : function(component, event, helper) {

        var schChildComp = component.find('childCmp');
        schChildComp.loadData(component.get('v.input1'),component.get('v.input2'));

        var rootElem = component.find('parent-div-id').getElement();

        var modalElem = rootElem.querySelector('#child-modal');
        modalElem.className = 'slds-modal slds-fade-in-open';
        var modalBackDropElem = rootElem.querySelector('#modal-backdrop');
        modalBackDropElem.className = 'slds-backdrop slds-backdrop--open';        
        return false;
    },
    closeModal : function(component){
        var rootElem = component.find('parent-div-id').getElement();

        var modalElem = rootElem.querySelector('#child-modal');
        modalElem.className = 'slds-modal';
        var modalBackFropElem = rootElem.querySelector('#modal-backdrop');
        modalBackFropElem.className = 'slds-backdrop'; 
    }
})

ModalComponent.cmp:

<aura:attribute name="arg1" type="String"></aura:attribute>
<aura:attribute name="arg2" type="String"></aura:attribute>

<aura:method name="loadData" action="{!c.loadData}"> 
    <aura:attribute name="p1" type="String"/>
    <aura:attribute name="p2" type="String"/>
</aura:method> 

Value 1 passed from parent: <aura:text value="{!v.arg1}"></aura:text><br/>
Value 2 passed from parent: <aura:text value="{!v.arg2}"></aura:text>

ModalComponentController.js:

({
    loadData : function(component, event, helper) {
        debugger;
        var params = event.getParam('arguments');
        component.set("v.arg1",params.p1);
        component.set("v.arg2",params.p2);
    }
})

Output:

enter image description here

NOTE: I am not seeing any lightning component related warnings in browser console.

Best Answer

The only time you need to call destroy explicitly is if you never add it to a body. If you do so, it will be destroyed automatically once removed. This is in the documentation:

Destroying Dynamically Created Components

After a component that is declared in markup is no longer in use, the framework automatically destroys it and frees up its memory.

If you create a component dynamically in JavaScript and that component isn't added to a facet (v.body or another attribute of type Aura.Component[]), you have to destroy it manually using Component.destroy() to avoid memory leaks.

So, in the general case, you don't ever need to call destroy, unless you never assigned it anywhere. The framework will clean up after you.

Q & A

Why do we need to destroy lightning components from the code?

You're not creating anything (there's no $A.createComponent), so no need to worry about destroying anything.

Don't lightning components get destroyed when user navigates to different url/page?

Yes, but they also get destroyed when they're no longer in the DOM anywhere. Remember that Lightning is a Single Page Application, and so the browser doesn't load/unload the page repeatedly. This provides a smoother user experience.

I think destroying components is something similar to garbage collection in java but besides performance improvements or there are any functional bugs in my implementation below

This implementation is just fine. The framework will create/destroy your components for you.

Related Topic