Keyed and unkeyed For
How For decides that an item is "the same row" depends on whether you pass key.
How For decides that an item is "the same row" depends on whether you pass key. The choice is read once, when For is created.
Unkeyed: <For each={xs}> |
Keyed: <For each={xs} key={(x) => x.id}> |
|
|---|---|---|
| Row is reused when | the item is the same value (===); equal primitives pair in order of occurrence |
key(item) equals the previous key (Map equality: NaN matches NaN) |
| Callback receives | the item value: (item, index) |
an accessor: (item, index), read it as item() |
| A new object with the same data | creates a new row, disposes the old one | keeps the row; item() now returns the new object |
index |
an accessor index() that follows the row |
same |
| Duplicate keys | not applicable | development warning EACH_KEY_DUPLICATE; later copies get fresh rows on every update |
Use the keyed form for data that arrives as fresh objects (API responses, reconciled stores) and for rows with their own state. Use the unkeyed form for lists of stable references or of primitives that never change identity while their position matters little.