When using the map() directive or just providing an iterable within the template, Lit creates a list of DOM nodes and updates them in the iteration order, efficiently reusing any previously rendered nodes. This technique should only be used when Lit controls all of the rendered state (as is commonly the case).
However, when relying instead on the DOM nodes to maintain state that isn't controlled by Lit, unexpected behavior can occur as the example below will demonstrate. In this case, use the repeat() directive instead.
Take a look at this example where each task item is rendered as a <li> with a checkbox using the map() directive. There are buttons to sort the list items in ascending or descending alphabetical order. The label text is provided by a template expression but there is no explicit component state to hold whether the item is checked or not.
Check one of the items and change the sort order. Notice that the item's label text changes but not the position of the checked box. This is because the checkbox state, which is not controlled by Lit, stays with the DOM nodes. During update, Lit only updates the value of the text node holding the label without reordering the DOM nodes.
Use the repeat() directive to keep the list item and checkbox tied to the specific item of the array. Using this directive with a key function lets Lit maintain the key-to-DOM association between updates by moving the DOM nodes when required.
Begin by importing the repeat() directive.
// my-element.ts
import {repeat} from'lit/directives/repeat.js';
// my-element.js
import {repeat} from'lit/directives/repeat.js';
Use repeat() in place of the map() directive, providing the iterable, a key function that returns a unique identifier for a particular item, and the template to render for each item.
Confirm that this is working correctly by checking an item and changing the sort order. The check mark should now move to stay next to its original label.
The key function provided must return a unique key for an item.
If you omit the key function—or provide a key function that simply returns the index—repeat() behaves exactly like map(). For more information, see the repeat
documentation. Also see
When to use map or repeat
for guidance on deciding when to use one or the other.