Lwc: [Feature] Public properties reflection

Created on 19 Dec 2018  路  4Comments  路  Source: salesforce/lwc

Today all class field marked with @api decorator are public properties. Reflecting a public property as an attribute requires a lot of boilerplate code to keep the internal component state in sync with the attribute.

import { LightningElement, api, track } from 'lwc';

export default class CustomInput extends LightningElement {
  @track _name;

  @api 
  get name() {
    return this._name; 
  }
  set name(val) {
    if (name == null) {
      this.removeAttribute('name');
    } else {
      this.setAttribute('name', val);
    }

    this._name = val;
  }
}

That being said, this approach doesn't solve the case where the attribute is updated and the property needs to be sync to the new value. This is because we don't expose the attributeChangedCallback.

One approach that has been discussed is to add an optional config bag to the api decorator. This config could have a reflect flag that would take care of reflecting the property to at the attribute.

import { LightningElement, api, track } from 'lwc';

export default class CustomInput extends LightningElement {
  @api({ reflect: true }) name; 
}
enhancement

Most helpful comment

I'm not a big fan of making it easy to reflect attributes. I think end users will suffer due to inconsistent APIs, and the only way to avoid that is to always reflect. If we do add this feature to the @api decorator, we should also provide some best practices around reflection. If we're not willing to do that, then maybe we should just let users implement their own @reflect decorator--it doesn't sound very difficult.

All 4 comments

for decorated fields, this is a very straight forward, but for accessors (setters specifically), this is tricky, let me list the issues:

  • should the value be reflected into the DOM before the setter is called?
  • if yes, then the value might not reflect the actual value from the getter
  • if no, then how to collect the value that should be reflected? invoking the getter is the only option but that's pretty bad because it is observable by the author (imagine counting the number of accesses?)

invoking the getter is the only option but that's pretty bad because it is observable by the author (imagine counting the number of accesses?)

We already have this effect elsewhere: access from the template. With future plans to memoize template accesses this鈥檒l get worse.

We should refine the invocation contract for getters so this and other behavior isn鈥檛 a surprise to developers.

I'm not a big fan of making it easy to reflect attributes. I think end users will suffer due to inconsistent APIs, and the only way to avoid that is to always reflect. If we do add this feature to the @api decorator, we should also provide some best practices around reflection. If we're not willing to do that, then maybe we should just let users implement their own @reflect decorator--it doesn't sound very difficult.

I'm with @ekashida on this after thinking a lot about this. We should bake that into @api.

Was this page helpful?
0 / 5 - 0 ratings