-
Notifications
You must be signed in to change notification settings - Fork 401
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
"key" attribute can be used outside of iteration #2697
Comments
This issue has been linked to a new work item: W-10713835 |
This is an interesting bug. I don't know if it's a conscious decision the component developer made to trick the engine. Effectively if the Ideally, it's something the template compiler should prohibit. But to avoid backward compat issues, I would suggest that the compiler ignores the I never took the time to properly formalize this, but I think that the current <template>
<template for:each={items} for:item="item">
<div key={item.id}>{item.name}</div>
<span key={item.id}>{item.value}</span>
</template>
</template> The [
{ type: VNodeType.Element, sel: 'div', key: 'foo-0' },
{ type: VNodeType.Element, sel: 'span', key: 'foo-1' },
{ type: VNodeType.Element, sel: 'div', key: 'bar-0' },
{ type: VNodeType.Element, sel: 'span', key: 'bar-1' },
// [ ... ]
] The correct approach would be to treat each item produced by the iteration as a VNode fragment, where each fragment can be reordered. In this approach, the fragment itself would have a key. [
{
type: VNodeType.Fragment,
key: 'foo',
children: [
{ type: VNodeType.Element, sel: 'div', key: '0' },
{ type: VNodeType.Element, sel: 'span', key: '1' },
]
},
{
type: VNodeType.Fragment,
key: 'bar',
children: [
{ type: VNodeType.Element, sel: 'div', key: '0' },
{ type: VNodeType.Element, sel: 'span', key: '1' },
]
}
// [ ... ]
] This brings me to the actual proposal. Instead of asking developers to add <template>
<template for:each={items} for:item="item" key={item.id}>
<div>{item.name}</div>
<span>{item.value}</span>
</template>
</template> This is effectively what other template-based frameworks are doing: I think it's something we can achieve while keeping backward compat. IMO, the template compiler can safely assume the |
I like this proposal. I would also suggest we name it For the record, I looked into this particular component, and the |
I think in the short-term, a good non-breaking solution would be to make |
Fixed in #2699 |
Description
During refactoring (#2677), we found a test in a downstream that broke because of an odd situation:
key
is intended to be used inside of an iteration. But it turns out, there's nothing to stop you from using it wherever you want. And if you do, you can create dynamic keys where the engine doesn't expect it.For the above example, the compiler generates:
Whenever this template rehydrates, it will go through the
updateStaticChildren
path, even though the vnodekey
may change every time.Steps to Reproduce
Version
LWC 2.9.x
Possible Solution
Only use the
key
attribute inside of an iteration.The text was updated successfully, but these errors were encountered: