Component Lifecycle

Lightning web components have a lifecycle managed by the framework. The framework creates components, adds and removes them from the DOM, and renders DOM updates whenever the state of a component changes.

A lifecycle hook is a JavaScript callback method triggered at a specific phase of a component instance’s lifecycle.

Lifecycle Flow

This diagram shows the flow of the component lifecycle from creation through render.

Shows the lifecycle flow of a component instance from creation through renderedCallback.

This is the flow of the component lifecycle when a component instance is removed from the DOM.

  1. Component is removed from the DOM.
  2. disconnectedCallback() is called on the component.
  3. Children are removed from the DOM.
  4. disconnectedCallback() is called on each child.

constructor()

The constructor() method is invoked when a component instance is created.

The constructor flows from parent to child.

To access the host element, use this.template. You can’t access child elements in the component body because they don’t exist yet. Properties are not passed yet, either. Properties are assigned to the component after construction and before the connectedCallback() hook.

These requirements from the HTML: Custom elements spec apply to the constructor().

Important

Don’t add attributes to the host element in the constructor. You can add attributes to the host element during any stage of the component lifecycle other than construction.

connectedCallback()

The connectedCallback() lifecycle hook is invoked when a component is inserted into the DOM.

This hook flows from parent to child.

To access the host element, use this. You can’t access child elements in the component body because they don’t exist yet.

The connectedCallback() hook can fire more than once. For example, if you remove an element and then insert it into another position, such as when you reorder a list, the hook is invoked several times. If you want code to run one time, write code to prevent it from running twice.

You can use connectedCallback() to add an attribute to the host element.

import { LightningElement } from 'lwc'
export default class New extends LightningElement {
    connectedCallback() {
        this.classList.add('new-class');
    }
}

You can also use connectedCallback() and disconnectedCallback() to register and unregister event listeners. The browser garbage collects DOM events, so you can choose not to unregister them. However, relying on garbage collection can lead to memory leaks. See Memory Management on MDN.

disconnectedCallback()

The disconnectedCallback() lifecycle hook is invoked when a component is removed from the DOM.

This hook flows from parent to child.

render()

For complex tasks like conditionally rendering a template or importing a custom one, use render() to override Lightning Web Components's standard rendering functionality. This function is invoked after connectedCallback() and must return a valid HTML template.

renderedCallback()

Note

This lifecycle hook is specific to Lightning Web Components, it isn’t from the HTML custom elements specification.

Called after every render of the component. This hook flows from child to parent.

When a component re-renders, all the expressions used in the template are reevaluated.

Due to mutations, a component is usually rendered many times during its lifespan in an application. 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.

Example

The LibsChartjs recipe in the Lightning Web Components recipes app uses the renderedCallback() lifecycle hook.

/* libsChartjs.js */
import { LightningElement, track } from 'lwc';

const generateRandomNumber = () => {
    return Math.round(Math.random() * 100);
};

export default class LibsChartjs extends LightningElement {
    @track error;
    chart;
    chartjsInitialized = false;

    config = {
      // Code removed for brevity
    };

    renderedCallback() {
        if (this.chartjsInitialized) {
            return;
        }
        this.chartjsInitialized = true;
        this.loadChartJs();
    }

    async loadChartJs() {
        await require(/* webpackChunkName: "chartJs" */ 'chart.js');
        const ctx = this.template
            .querySelector('canvas.donut')
            .getContext('2d');
        this.chart = new window.Chart(ctx, this.config);
    }
}

errorCallback(error, stack)

Note

This lifecycle hook is specific to Lightning Web Components, it isn’t from the HTML custom elements specification.

Called when a descendant component throws an error in one of its lifecycle hooks. The error argument is a JavaScript native error object, and the stack argument is a string.

Implement this hook to create an error boundary component that captures errors in all the descendant components in its tree. The error boundary component can log stack information and render an alternative view to tell users what happened and what to do next. The method works like a JavaScript catch{} block for components that throw errors in their lifecycle hooks. It’s important to note that an error boundary component catches errors only from its children, and not from itself.

You can create an error boundary component and reuse it throughout an app. It’s up to you where to define those error boundaries. You can wrap the entire app, or every individual component. Most likely, your architecture will fall somewhere in between. A good rule of thumb is to think about where you’d like to tell users that something went wrong.

This example implements the errorCallback() method.

<!-- boundary.html -->
<template>
    <template if:true={this.error}>
        <error-view error={this.error} info={this.stack}></error-view>
    </template>
    <template if:false={this.error}>
        <healthy-view></healthy-view>
    </template>
</template>
// boundary.js
import { LightningElement, track } from 'lwc';
export default class Boundary extends LightningElement {
    @track error;
    @track stack;
    errorCallback(error, stack) {
        this.error = error;
    }
}

You don’t have to use if:[true|false] in a template. For example, let’s say you define a single component template. If this component throws an error, the framework calls errorCallback and unmounts the component during re-render.

<!-- boundary.html -->
<template>
  <my-one-and-only-view></my-one-and-only-view>
</template>

Note

The errorCallback() hook doesn’t catch errors like click callbacks and async operations that fall outside of the component lifecycle (constructor(), connectedCallback(), render(), renderedCallback()). It’s also important to note that errorCallback() isn’t a JavaScript try/catch, it’s a component lifecycle guard.