Use Item Types for Heterogeneous Lists
Use Item Types for Heterogeneous Lists
Section titled “Use Item Types for Heterogeneous Lists”When a list has different item layouts (messages, images, headers, etc.), use a
type field on each item and provide getItemType to the list. This puts items
into separate recycling pools so a message component never gets recycled into an
image component.
Incorrect (single component with conditionals):
type Item = { id: string; text?: string; imageUrl?: string; isHeader?: boolean }
function ListItem({ item }: { item: Item }) { if (item.isHeader) { return <HeaderItem title={item.text} /> } if (item.imageUrl) { return <ImageItem url={item.imageUrl} /> } return <MessageItem text={item.text} />}
function Feed({ items }: { items: Item[] }) { return ( <LegendList data={items} renderItem={({ item }) => <ListItem item={item} />} recycleItems /> )}Correct (typed items with separate components):
type HeaderItem = { id: string; type: 'header'; title: string }type MessageItem = { id: string; type: 'message'; text: string }type ImageItem = { id: string; type: 'image'; url: string }type FeedItem = HeaderItem | MessageItem | ImageItem
function Feed({ items }: { items: FeedItem[] }) { return ( <LegendList data={items} keyExtractor={(item) => item.id} getItemType={(item) => item.type} renderItem={({ item }) => { switch (item.type) { case 'header': return <SectionHeader title={item.title} /> case 'message': return <MessageRow text={item.text} /> case 'image': return <ImageRow url={item.url} /> } }} recycleItems /> )}Why this matters:
- Recycling efficiency: Items with the same type share a recycling pool
- No layout thrashing: A header never recycles into an image cell
- Type safety: TypeScript can narrow the item type in each branch
- Better size estimation: Use
getEstimatedItemSizewithitemTypefor accurate estimates per type
<LegendList data={items} keyExtractor={(item) => item.id} getItemType={(item) => item.type} getEstimatedItemSize={(index, item, itemType) => { switch (itemType) { case 'header': return 48 case 'message': return 72 case 'image': return 300 default: return 72 } }} renderItem={({ item }) => { /* ... */ }} recycleItems/>Reference: LegendList getItemType