javascriptweb-componentlit-elementlit-htmllit

Suggest a way to make lit-element reactive properties work with ecma 2022 private fields


Recently we got a new ECMA 2022 standard approved and there is now a syntax to support private fields natively by prefixing # to the name. For years we have been using _ conventionally and now there is some space for confusion of # and _.

The problem: If you now declare a private field and add it to lit-element properties, it would not work. The component will not update on change for a property that is declared with # syntax.

class ExtendedLitElement extends LitElement {
  #somePrivateField
  
  static get properties() {
    return {
      '#somePrivateField': Array,
    }
  }
}

Whenever you do:

this.#somePrivateField = [1, 2, 3];

An element will not be updated. Is there a way to register # prefixed private field as a lit property?


Solution

  • Currently JS class fields, whether public or private, cannot be used for reactive properties. This is due to class fields being defined on the instance whereas reactive properties are defined as accessors on the prototype. Having a class field masks the reactive property accessor.

    See: https://lit.dev/docs/components/properties/#avoiding-issues-with-class-fields

    You would have to continue using _ prefixed reactive properties or manually invoke this.requestUpdate() after setting a class field to trigger an update.