Search code examples
lit-elementlit

LitElement EventListener() not update render() function


I have two Lit components that are at the same level but when the first component sends data to the second component using a dispatchEvent, the second component's render method is not updated.

html file

<div>
    <test-input></test-input>
    <test-button></test-button>
</div>

javascript file

export class TestButton extends LitElement {
    constructor() {
        super();
    }
    
    render() {
        return html`<button @click="${this._onClickHandler}">send</button>`;
    }

    _onClickHandler(event){
        let target = event.originalTarget;
        const options = {
            detail: { message: target.innerText },
            bubbles: true,
            composed: true
        }
        let buttonEvent = new CustomEvent('inputreceiver', options);
        this.dispatchEvent(buttonEvent);
    }
}
customElements.define('test-button', TestButton);


export class Display extends LitElement {
    static properties = {
        content: {type: String}
    };

    constructor() {
        super();
        this.content = '0.00';
    }

    connectedCallback() {
        super.connectedCallback();
        window.addEventListener('inputreceiver', this._onChangeContent);
    }
    
    disconnectedCallback() {
        window.removeEventListener('inputreceiver', this._onChangeContent);
        super.disconnectedCallback();
    }

    render() {
        return html`
            <p class="display">value: ${this.content}</p>
        `;
    }

    _onChangeContent(event){
        this.content = event.detail.message;
    }
}
customElements.define('test-input', Display);

I'm learning litJS and I want to send parameters from one component to another. But when I want to show the value obtained from the first component in the second component, the render method doesn't work for me.


Solution

  • Currently this in your _onChangeContent function will be bound to window when adding your event listener.

    Instead try defining _onChangeContent as an instance via an arrow function as recommended by @Augustine Kim:

        _onChangeContent = (event) => {
            this.content = event.detail.message;
        }

    or by passing an anonymous arrow function to your event listener. Note that this will stop you from being able to remove this event listener as no reference to the anonymous function is kept.

        connectedCallback() {
            super.connectedCallback();
            window.addEventListener('inputreceiver', (e) => this._onChangeContent(e));
        }

    This will ensure that this is bound to your component test-input.