React Patterns & Best PracticesEntry 7 of 10
Dynamic Keys with itemKeyFn
A function prop that tells a generic list how to get a unique key from each item, since the list doesn't know the item's shape.
Notes
- Using the array index as
keybreaks when the list is filtered: React reuses DOM elements for the wrong items. SearchableListcan't assumeitem.idexists; strings don't have one.- The consumer passes
itemKeyFn:(place) => place.idfor objects,(item) => itemfor strings. - Angular's
@forhas the same need:trackmust identify each item, and the same function can drive it.
What / Why / When
- What
Consumer-supplied identity for list items.
- Why
Correct DOM reuse and state preservation in generic lists.
- When
Any reusable list or table component.
Code compare
<li key={itemKeyFn(item)}>{children(item)}</li><SearchableList items={PLACES} itemKeyFn={(place) => place.id}>...</SearchableList><SearchableList items={['item 1', 'item 2']} itemKeyFn={(item) => item}>...</SearchableList>@for (item of searchResults(); track itemKeyFn()(item)) { ... }Quick reference
| React | Angular |
|---|---|
key={itemKeyFn(item)} | track itemKeyFn()(item) |
❌ key={index} on filtered lists | ❌ track $index on filtered lists |