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 key breaks when the list is filtered: React reuses DOM elements for the wrong items.
  • SearchableList can't assume item.id exists; strings don't have one.
  • The consumer passes itemKeyFn: (place) => place.id for objects, (item) => item for strings.
  • Angular's @for has the same need: track must 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

React
<li key={itemKeyFn(item)}>{children(item)}</li>
React
<SearchableList items={PLACES} itemKeyFn={(place) => place.id}>...</SearchableList><SearchableList items={['item 1', 'item 2']} itemKeyFn={(item) => item}>...</SearchableList>
Angular
@for (item of searchResults(); track itemKeyFn()(item)) { ... }

Quick reference

ReactAngular
key={itemKeyFn(item)}track itemKeyFn()(item)
❌ key={index} on filtered lists❌ track $index on filtered lists