Skip to content

Lifecycle

DNA components follow the Custom Element lifecycle specification, with the addition of the propertyChangedCallback and render methods. The complete list of methods is:

initialize

The initialize method is invoked at the end of the final constructor. It initializes inital property values and observers, as well as listeners.

ts
import { Component, customElement } from '@chialab/dna';
import './MyToc';

@customElement('my-article')
export class MyArticle extends Component {
    toc = new MyToc();

    initialize() {
        super.initialize();
        this.toc.observe('active', (oldValue, newValue) => {
            this.scrollToSelector(newValue);
        });
    }

    scrollToSelector(selector: string) {
        // ...
    }
}

connectedCallback

From MDN:

Invoked each time the custom element is appended into a document-connected element. This will happen each time the node is moved, and may happen before the element's contents have been fully parsed. connectedCallback may be called once your element is no longer connected, use Node.isConnected to make sure.

ts
import { Component, customElement } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    parentSection: HTMLElement | null = null;

    connectedCallback() {
        super.connectedCallback();
        this.parentSection = this.closest('section');
    }
}

disconnectedCallback

From MDN:

Invoked each time the custom element is disconnected from the document's DOM.

ts
import { Component, customElement } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    parentSection: HTMLElement | null = null;

    disconnectedCallback() {
        super.disconnectedCallback();
        this.parentSection = null;
    }
}

attributeChangedCallback

From MDN:

Invoked each time one of the custom element's attributes is added, removed, or changed.

The method receives the attribute name as first argument, as well as the new value and the previous value (default null).

ts
import { Component, customElement } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    static get observedAttributes() {
        return ['tabindex', ...super.observedAttributes];
    }

    attributedChangedCallback(attributeName: string, oldValue: string | null, newValue: string | null) {
        switch (attributeName) {
            case 'tabindex':
                if (oldValue === '-1') {
                    this.style.opacity = '0.5';
                } else {
                    this.style.opacity = '1';
                }
                break;
            default:
                super.attributeChangedCallback(attributeName, oldValue, newValue);
        }
    }
}

propertyChangedCallback

This method is very similar to attributeChangedCallback and it is invoked each time one of the element's property is changed.

The signature is equivalent too: it receives the property name as first argument, as well as the new value and the previous value (default undefined).

stateChangedCallback

The same of propertyChangedCallback, but for state properties.

render

This method is invoked each time the component should be rendered. It returns a template that will be rendered in the component's realm.

tsx
import { Component, customElement } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    render() {
        return (
            <article>
                <h1>{this.title}</h1>
                <slot></slot>
                <time>{this.lastUpdate}</time>
            </article>
        );
    }
}

updatedCallback

This method is invoked each time the component is updated and re-rendered.

ts
import { Component, customElement } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    updatedCallback() {
        super.updatedCallback();
        this.landmarks = this.querySelectorAll('h1, h2, h3, h4, h5, h6');
    }
}

shouldUpdate

This method is invoked each time a property or state property is changed. It returns a boolean value that indicates if the component should be updated or not. By default, it returns true.

ts
import { Component, customElement, property } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    @property({ type: Date })
    lastUpdate = new Date();

    shouldUpdate(property, oldValue, newValue) {
        if (property === 'lastUpdate') {
            return newValue.valueOf() !== oldValue.valueOf();
        }
        return super.shouldUpdate(property, oldValue, newValue);
    }
}

requestUpdate

This method is invoked each time a property or state property is changed and the component needs a re-render. If a re-render is already scheduled, the method does nothing.

ts
import { Component, customElement, listen } from '@chialab/dna';

@customElement('my-article')
export class MyArticle extends Component {
    @listen('click', 'button')
    showMore() {
        this.parentSection.style.overflow = 'visible';
        this.requestUpdate();
    }
}

forceUpdate

This method is invoked each time a property or state property is changed and the component should perform a re-render.

Released under the MIT License.