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

PropTypeDescription
dataarrayData source
renderItem({ item, index, separators }) => ReactNodeRender each row
keyExtractor(item, index) => stringUnique key per item

Performance

PropDefaultDescription
initialNumToRender10Items rendered on first paint
maxToRenderPerBatch10Items per render batch
windowSize21Render window (×viewport height)
removeClippedSubviewsfalseUnmount off-screen views (Android)
getItemLayoutSkip layout measurement for fixed-height rows
updateCellsBatchingPeriod50ms between batches

Layout

PropTypeDescription
horizontalbooleanHorizontal scroll
numColumnsnumberGrid columns (requires same row height)
columnWrapperStylestyleStyle for each row in multi-column
invertedbooleanInvert scroll direction
contentContainerStylestyleStyle for inner scroll container

Headers / Footers / Separators

PropTypeDescription
ListHeaderComponentcomponentRendered above first item
ListFooterComponentcomponentRendered below last item
ListEmptyComponentcomponentRendered when data is empty
ItemSeparatorComponentcomponentBetween each item (not after last)
ListHeaderComponentStylestyle
ListFooterComponentStylestyle

Scroll & Events

PropTypeDescription
onEndReached({ distanceFromEnd }) => voidTriggered near bottom
onEndReachedThresholdnumberFraction of list height (default 0.5)
onRefreshfunctionPull-to-refresh handler
refreshingbooleanPull-to-refresh spinner state
onScroll({ nativeEvent }) => voidScroll events
scrollEventThrottlenumberms between scroll events (iOS)
onViewableItemsChanged({ viewableItems, changed }) => voidVisibility events
viewabilityConfigobjectControls 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}
/>

getItemLayout is the single biggest FlatList optimization — eliminates measurement passes and enables scrollToIndex.

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: scrollToIndex requires getItemLayout unless 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

PropDescription
sections[{ title, data, renderItem?, keyExtractor? }]
renderSectionHeader({ section }) => ReactNode
renderSectionFooter({ section }) => ReactNode
stickySectionHeadersEnabledStick headers on scroll (default true on iOS)
SectionSeparatorComponentBetween 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 FlashList when FlatList performance is inadequate — it recycles cells at the JS level instead of relying on removeClippedSubviews.