lwc icon indicating copy to clipboard operation
lwc copied to clipboard

List re-rendering causes DOM state to be lost

Open nolanlawson opened this issue 1 year ago • 1 comments

Description

When using a template list (for:each or iterator:*), if that list contains other LWC components, then after a reordering of the list, it is possible for a component to be destroyed/recreated, which causes DOM state (such as focus or the play state of a <video>) to be lost.

Steps to Reproduce

For example:

    <template for:each={keys} for:item="key">
      <x-component key={key} uuid={key}></x-component>
    </template>

If the original keys is [1,2,3], and then an <input> inside of #2 is focused, and then the list is reordered to [1,3,2], then #2 will be unmounted/remounted (destroyed/recreated), causing focus inside of the <input> to be lost.

Note that this does not happen for the 1st or 3rd item in the list; it is a quirk of LWC's diffing algorithm.

Repro

Expected Results

DOM state should be kept after reordering.

Actual Results

DOM state is lost after reordering.

Possible Solution

The only way to work around this is to save the focus state outside of the component (e.g. in localStorage) when the component is unmounted and then restore it upon remount.

Also note that fixing this inside of LWC would be an observable change, so could break consumers who rely on the destroy/recreate behavior.

nolanlawson avatar Jun 12 '24 22:06 nolanlawson

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

git2gus[bot] avatar Jun 12 '24 22:06 git2gus[bot]