Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactivity only works for non-bracket-notation string properties #4547

Open
nolanlawson opened this issue Sep 12, 2024 · 4 comments
Open

Reactivity only works for non-bracket-notation string properties #4547

nolanlawson opened this issue Sep 12, 2024 · 4 comments

Comments

@nolanlawson
Copy link
Collaborator

nolanlawson commented Sep 12, 2024

const symbol = Symbol("haha")
export default class extends LightningElement {
  reg = 'regular!';
  ["with spaces"] = 'spaces!';
  [1337] = 'number!';
  [symbol] = 'symbol!';
}

In the above example, only reg is a reactive property. The other properties are non-reactive, because @lwc/babel-plugin-component does not recognize them as reactive properties and doesn't register them as such:

registerDecorators(App, {
  fields: ["reg"]
});

Repro showing reactivity not working correctly

This is definitely an edge case of an edge case, but maybe it's something we should support? If not, it's at least worth documenting in this GitHub issue.

Full repro for posterity
<template>
    <strong>Regular</strong>: {regular}
    <strong>Spaces</strong>: {spaces}
    <strong>Number</strong>: {number}
    <strong>Symbol</strong>: {symbol}
</template>
import { LightningElement } from 'lwc';

const symbol = Symbol("haha")
let count = 0
export default class App extends LightningElement {
  reg = 'regular!';
  ["with spaces"] = 'spaces!';
  [1337] = 'number!';
  [symbol] = 'symbol!';

  get regular() {
    return this.reg
  }

  get spaces() {
    return this['with spaces']
  }

  get number() {
    return this[1337]
  }

  get symbol () {
    return this[symbol]
  }

  renderedCallback() {
    if (++count) {
      setTimeout(() => {
        this.reg = 'regular 2!'
        setTimeout(() => {
          this['with spaces'] = 'spaces 2!'
          this[1337] = 'number 2!'
          this[symbol] = 'symbol 2!'
        })
      })
    }
  }
}
@wjhsf
Copy link
Contributor

wjhsf commented Sep 12, 2024

To be more specific, it seems that reactivity only works when the prop is a valid identifier -- quoted "reg" is a string literal, and does not work. Similarly, 1337 is not a computed prop, but still does not work because it is a numeric literal.

@cardoso
Copy link
Contributor

cardoso commented Sep 15, 2024

To be more specific, it seems that reactivity only works when the prop is a valid identifier -- quoted "reg" is a string literal, and does not work. Similarly, 1337 is not a computed prop, but still does not work because it is a numeric literal.

@wjhsf I included tests for those cases in my PR

@cardoso
Copy link
Contributor

cardoso commented Sep 24, 2024

@nolanlawson could you update this issue with your latest thoughts? Thanks!

@nolanlawson
Copy link
Collaborator Author

My current thinking:

It occurred to me that we still don't support decorators (@api, @track, @wire) on these computed properties. So it's not really a full solution.

I feel like it might make more sense to just document this as a limitation of the framework, and then focus on fixing it once browsers have native support for decorators. At that point, it would be easy to support these decorators at the syntax level (since we wouldn't need our own Babel plugin), and we could potentially get rid of registerDecorators altogether which would resolve the reactivity issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants