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

Allow shorthand for directives like lwc:ref #3303

Open
AllanOricil opened this issue Jan 20, 2023 · 8 comments
Open

Allow shorthand for directives like lwc:ref #3303

AllanOricil opened this issue Jan 20, 2023 · 8 comments
Labels

Comments

@AllanOricil
Copy link
Contributor

AllanOricil commented Jan 20, 2023

Is your feature request related to a problem? Please describe.

no, I just would like to know if it could be simplified. And nice feature, by the way. We can get rid of data-id parameters in our templates.

https://developer.salesforce.com/blogs/2023/01/lwc-enhancements-for-developers-learn-moar-spring-23
image

Is there a reason for prepending "ref" with the word "lwc:" ?

Couldn't it just be

<div :ref="reference"></div>
<div ref="reference"></div>

Vue and React template engines are able to use just "ref", so I believe lwc would also be able to do it. It would be good if you could try to follow what other frameworks did well, so that people that are used to one of them can learn lwc faster. I only see benefits doing so.

Another question, does it accept expressions?

Like,

<div ref={dynamicRef}></div>
<template for:each={bla} for:item="blas">
    <div ref={bla}></div>
</template>
<template for:each={bla} for:item="blas">
     <div ref={getDynamicRef(bla)}></div>
</template>
@nolanlawson
Copy link
Collaborator

nolanlawson commented Jan 20, 2023

Thanks for the feedback!

Is there a reason for prepending "ref" with the word "lwc:" ?

Yep, as mentioned in #2503 (comment), this is to make it clear what is native to the web platform and what is part of LWC. This tells developers whether they should be searching for documentation on MDN or on Salesforce/lwc.dev. 🙂

Another question, does it accept expressions?

No. lwc:ref must be a static string value. The for:each use case is something we specifically called out in the RFC as not yet implemented, but worth implementing. I opened an issue to track that: #3304

Closing this issue, as we don't currently plan to shorten lwc:ref to ref. Thanks again for the feedback!

@nolanlawson
Copy link
Collaborator

nolanlawson commented Jan 20, 2023

Reopening this. After some internal discussion, it seems that it may be reasonable to support :ref in addition to lwc:ref. In fact, this is doable for all the lwc:* directives: :if, :render-mode, :preserve-comments, etc.

This might also be a good time to harmonize some of the directives that don't start with lwc:, e.g.:

  • for:each -> lwc:each (/ht @jmsjtu)
  • key -> lwc:key

The above two could be done in a backwards-compatible way; they would just be synonyms.

@nolanlawson nolanlawson changed the title remove lwc keyword from the ref feature Allow shorthand for directives like lwc:ref Jan 20, 2023
@git2gus
Copy link

git2gus bot commented Jan 20, 2023

This issue has been linked to a new work item: W-12415033

@AllanOricil
Copy link
Contributor Author

AllanOricil commented Jan 22, 2023

@nolanlawson @jmsjtu

for:each becoming lwc:each feels not natural.

In my opinion, reading for:each={contacts} has always been weird because when I say/write the word each in english, the next word must be a singular one. For instance, I can't write or speak "for each bananas" in english. If I wanted to use plural, I would have to write it like "for each of these bananas".
With that said, the argument is that you should remove the word each because it does not feel grammarly correct or natural when writing/speaking the directive using a plural word.

I would love if you could actually change the for:each directive entirely. Something like:

for:each={item in collection}
for:each={(item, index) in collection}

I also believe that joining the two directives in one will simplify the template engine because you won't need to parse separately 2 directives and then merge their information before validating if it is correct or not.

It is similar to vue. The only difference is the addition of the word each, which I think it makes the directive sound better. I don't know, but I have the impression that I won't forget it if I stop using it. I won't need to look up the docs just to remember how to do a for each in lwc.

would be much better because it would reduce the amount of characters in a template, while also respecting the English grammar and keeping the word each. I could not find a RFC discussion about this improvement.

But if you can't really change it. What about using lwc:for and lwc:item? Then the correspondent shorthands would be:
:for, :item and :key

@caridy
Copy link
Contributor

caridy commented Jan 25, 2023

I'm up for shorting lwc: to just :, but I will probably continue to use lwc: myself, so it is very clear that this is intended to be LWC specific... the namespacing of HTML attributes is very clear, we namespace to prevent collisions.

@pmdartus
Copy link
Member

As always thanks for raising this @AllanOricil.

I am also up for finishing the migration of all the LWC directives to lwc:* and enabling a shorthand version with the : prefix.

Over the last 5 years, we have learned how LWC developers are using the existing directives. And as part of the harmonization process, I would like to make sure we also fix some of the design flaws in the for:each directive:

  • Have the lwc:key directive applied to the same element as the lwc:each directive. Currently, the key is applied to the children elements, which makes very little sense and prevents some optimizations like the usage of fragments in the diffing algo.
  • Make the key directive optional. I have seen components having to create a unique id using Math.random() just to use it as a value for the key directive.
  • Exposing the current index of the iteration without having to use the iterator:* directive.

@AllanOricil
Copy link
Contributor Author

AllanOricil commented Jan 27, 2023

As always thanks for raising this @AllanOricil.

I am also up for finishing the migration of all the LWC directives to lwc:* and enabling a shorthand version with the : prefix.

Over the last 5 years, we have learned how LWC developers are using the existing directives. And as part of the harmonization process, I would like to make sure we also fix some of the design flaws in the for:each directive:

  • Have the lwc:key directive applied to the same element as the lwc:each directive. Currently, the key is applied to the children elements, which makes very little sense and prevents some optimizations like the usage of fragments in the diffing algo.
  • Make the key directive optional. I have seen components having to create a unique id using Math.random() just to use it as a value for the key directive.
  • Exposing the current index of the iteration without having to use the iterator:* directive.

@pmdartus
Another question, If I mutate an array that is used in a for:each does lwc recreate all the elements in the DOM, or does it patch and remove the ones that are no longer used?
For example: a for loop rendered 1000 todo items, and then the todo Items array is mutaded

this.todoItems = this.todoItems.filter((t)=>t.include))

Does lwc throw away all 1000 elements from the DOM and then mount new ones, or does it patch some elements and unmount the ones that were deleted from the array?

Not sure how Vue does it, but their doc says it has a "smart heurist algorithm" that it is used to avoid unnecessary changes to the DOM when an array used in a for loop is mutated. So, if lwc does not currently have something like this, maybe this could be another good optimization you could implement.

@pmdartus
Copy link
Member

Another question, If I mutate an array that is used in a for:each does lwc recreate all the elements in the DOM, or does it patch and remove the ones that are no longer used?

Yes, it's something that is baked into LWC rendering engine from day 1.
This is the reason why template iterations require a stable key directive. This key enables the engine to map items between 2 rendering cycles to apply the minimal set of DOM operations.

You can find this logic in here in LWC, and here in Vue.

@AllanOricil AllanOricil closed this as not planned Won't fix, can't repro, duplicate, stale Mar 3, 2023
@nolanlawson nolanlawson reopened this Mar 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants