React Native Cheatsheet
Lists (FlatList)
Use this React Native reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
FlatList — Core Usage
FlatList renders items lazily and recycles off-screen cells. Use it for any list longer than ~20 items.
import { FlatList, Text, View } from 'react-native'; const DATA = [ { id: '1', title: 'Item One' }, { id: '2', title: 'Item Two' }, ]; <FlatList data={DATA} keyExtractor={(item) => item.id} renderItem={({ item, index, separators }) => ( <View style={{ padding: 16 }}> <Text>{item.title}</Text> </View> )} />
FlatList Props Reference
Required
| Prop | Type | Description |
|---|---|---|
data | array | Data source |
renderItem | ({ item, index, separators }) => ReactNode | Render each row |
keyExtractor | (item, index) => string | Unique key per item |
Performance
| Prop | Default | Description |
|---|---|---|
initialNumToRender | 10 | Items rendered on first paint |
maxToRenderPerBatch | 10 | Items per render batch |
windowSize | 21 | Render window (×viewport height) |
removeClippedSubviews | false | Unmount off-screen views (Android) |
getItemLayout | — | Skip layout measurement for fixed-height rows |
updateCellsBatchingPeriod | 50 | ms between batches |
Layout
| Prop | Type | Description |
|---|---|---|
horizontal | boolean | Horizontal scroll |
numColumns | number | Grid columns (requires same row height) |
columnWrapperStyle | style | Style for each row in multi-column |
inverted | boolean | Invert scroll direction |
contentContainerStyle | style | Style for inner scroll container |
Headers / Footers / Separators
| Prop | Type | Description |
|---|---|---|
ListHeaderComponent | component | Rendered above first item |
ListFooterComponent | component | Rendered below last item |
ListEmptyComponent | component | Rendered when data is empty |
ItemSeparatorComponent | component | Between each item (not after last) |
ListHeaderComponentStyle | style | |
ListFooterComponentStyle | style |
Scroll & Events
| Prop | Type | Description |
|---|---|---|
onEndReached | ({ distanceFromEnd }) => void | Triggered near bottom |
onEndReachedThreshold | number | Fraction of list height (default 0.5) |
onRefresh | function | Pull-to-refresh handler |
refreshing | boolean | Pull-to-refresh spinner state |
onScroll | ({ nativeEvent }) => void | Scroll events |
scrollEventThrottle | number | ms between scroll events (iOS) |
onViewableItemsChanged | ({ viewableItems, changed }) => void | Visibility events |
viewabilityConfig | object | Controls what "viewable" means |
Fixed-Height Optimization
const ITEM_HEIGHT = 72; <FlatList data={DATA} getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })} renderItem={({ item }) => ( <View style={{ height: ITEM_HEIGHT, justifyContent: 'center', padding: 16 }}> <Text>{item.title}</Text> </View> )} keyExtractor={(item) => item.id} />
getItemLayoutis the single biggest FlatList optimization — eliminates measurement passes and enablesscrollToIndex.
Pagination / Infinite Scroll
const [data, setData] = React.useState([]); const [page, setPage] = React.useState(1); const [loading, setLoading] = React.useState(false); const [hasMore, setHasMore] = React.useState(true); const loadMore = async () => { if (loading || !hasMore) return; setLoading(true); const newItems = await fetchItems(page); if (newItems.length === 0) setHasMore(false); setData(prev => [...prev, ...newItems]); setPage(p => p + 1); setLoading(false); }; <FlatList data={data} keyExtractor={(item) => item.id} renderItem={({ item }) => <ItemCard item={item} />} onEndReached={loadMore} onEndReachedThreshold={0.3} ListFooterComponent={loading ? <ActivityIndicator /> : null} />
Pull-to-Refresh
import { FlatList, RefreshControl } from 'react-native'; const [refreshing, setRefreshing] = React.useState(false); const onRefresh = async () => { setRefreshing(true); await fetchData(); setRefreshing(false); }; <FlatList data={DATA} keyExtractor={(item) => item.id} renderItem={({ item }) => <ItemRow item={item} />} refreshControl={ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor="#007AFF" colors={['#007AFF']} // Android /> } />
Grid Layout
<FlatList
data={DATA}
numColumns={3}
keyExtractor={(item) => item.id}
columnWrapperStyle={{ gap: 8, paddingHorizontal: 16 }}
contentContainerStyle={{ gap: 8, paddingVertical: 16 }}
renderItem={({ item }) => (
<View style={{ flex: 1, aspectRatio: 1, backgroundColor: '#eee' }}>
<Image source={{ uri: item.image }} style={{ flex: 1 }} />
</View>
)}
/>Scroll to Index / Offset
const listRef = React.useRef(null); <FlatList ref={listRef} ... /> // Scroll to item by index listRef.current?.scrollToIndex({ index: 5, animated: true }); // Scroll to offset in px listRef.current?.scrollToOffset({ offset: 500, animated: true }); // Scroll to end listRef.current?.scrollToEnd({ animated: true });
Gotcha:
scrollToIndexrequiresgetItemLayoutunless all items before the target have already rendered.
SectionList
Groups items under section headers.
import { SectionList, Text, View } from 'react-native'; const SECTIONS = [ { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] }, { title: 'Veggies', data: ['Carrot', 'Pea'] }, ]; <SectionList sections={SECTIONS} keyExtractor={(item, index) => item + index} renderItem={({ item }) => ( <Text style={{ padding: 12 }}>{item}</Text> )} renderSectionHeader={({ section: { title } }) => ( <Text style={{ fontWeight: 'bold', backgroundColor: '#f0f0f0', padding: 8 }}> {title} </Text> )} stickySectionHeadersEnabled />
SectionList-specific props
| Prop | Description |
|---|---|
sections | [{ title, data, renderItem?, keyExtractor? }] |
renderSectionHeader | ({ section }) => ReactNode |
renderSectionFooter | ({ section }) => ReactNode |
stickySectionHeadersEnabled | Stick headers on scroll (default true on iOS) |
SectionSeparatorComponent | Between sections |
VirtualizedList (Low-level)
FlatList and SectionList are built on VirtualizedList. Use only when you have non-array data.
import { VirtualizedList } from 'react-native'; <VirtualizedList data={DATA} initialNumToRender={4} renderItem={({ item }) => <Item title={item.title} />} keyExtractor={(item) => item.id} getItemCount={(data) => data.length} getItem={(data, index) => data[index]} />
FlashList (Community — Faster)
Drop-in replacement for FlatList with dramatically better performance.
npm install @shopify/flash-list cd ios && pod install
import { FlashList } from '@shopify/flash-list'; <FlashList data={DATA} renderItem={({ item }) => <ItemCard item={item} />} estimatedItemSize={72} // Required: average item height keyExtractor={(item) => item.id} />
Use
FlashListwhen FlatList performance is inadequate — it recycles cells at the JS level instead of relying onremoveClippedSubviews.