1

I have the following code

render () {
     return html`<panel>${mobile
        ? html`${this.renderPane("side")}`
         :
         html `${this.renderPane("bottom")}`
      `
}

renderPane(slot: string) {
   return html `<x slot=${slot} .mobile=${this._isMobile}></x>`;
}

For some reason, when I resize the screen (mobile = true), the constructor for "x" lit element gets called again, and disconnectedCallback gets called, which removes the listeners that I added to connectedCallback. Does anyone know why that's happening?

Chris Hansen
  • 7,813
  • 15
  • 81
  • 165
  • if disconnectedCallback is triggered the Node is removed from the DOM. So yes, when the Node is added to the code again, the constructor is called – Danny '365CSI' Engelman Oct 20 '22 at 13:47
  • How do I make sure that the constructor is only called once? Also the disconnectedCallback is being called on the new instance @Danny'365CSI'Engelman – Chris Hansen Oct 20 '22 at 17:40

1 Answers1

2

Lit creates new DOM nodes when templates are swapped.

Instead of rendering different templates with the ternary, change only the attribute expression.

You have some invalid element tags in your question. I'm going to assume <panel> and <x> are some custom elements, and that mobile is a class field since I don't see where this is defined.

render () {
  return html`
    <panel-foo>
      <x-bar
        slot=${this.mobile ? 'side' : 'bottom'}
        .mobile=${this._isMobile}></x-bar>
    </panel-foo>`
  `;
}

This isn't a guarantee if there are conditional renders happening in trees above this.

I don't know how you're removing event listeners on disconnectedCallback but you probably want to make that independent of other instances. This can also matter if you have multiple instances of this element on the page.

Augustine Kim
  • 841
  • 1
  • 5
  • 1
    What do you mean by "when templates are swapped"? – Chris Hansen Oct 20 '22 at 20:35
  • 1
    In your original code, when the condition of `mobile` changes, a different call of `html` happens. Lit wouldn't know that they both end up creating the same custom element so it will remove the previously rendered DOM element and create a new DOM element, hence the additional constructor call. – Augustine Kim Oct 21 '22 at 00:13