Skip to main content

Layout Configuration

horizontal
boolean | null | undefined
default:"false"
If true, renders items next to each other horizontally instead of stacked vertically.
<FlashList
  data={items}
  renderItem={renderItem}
  horizontal
/>
numColumns
number
default:"1"
Multiple columns can only be rendered with horizontal={false} and will zig-zag like a flexWrap layout. Items should all be the same height - masonry layouts are not supported (except on New Architecture with masonry prop).
<FlashList
  data={items}
  renderItem={renderItem}
  numColumns={2}
/>
For masonry layouts with varying item heights, use the masonry prop (New Architecture only).
masonry
boolean
default:"false"
Enable masonry layout for grid layouts with varying item heights.
<FlashList
  data={items}
  renderItem={renderItem}
  numColumns={2}
  masonry
/>
optimizeItemArrangement
boolean
default:"false"
If enabled, MasonryFlashList will try to reduce difference in column height by modifying item order.
<FlashList
  data={items}
  renderItem={renderItem}
  numColumns={2}
  masonry
  optimizeItemArrangement
/>

Styling Props

style
StyleProp<ViewStyle>
Style for the RecyclerView’s parent container. Please avoid anything which can mess size of children in this view. For example, margin is okay but padding is not.
To enable overflow: "visible", you must also set it on the internal ScrollView via overrideProps:
<FlashList
  style={{ overflow: "visible" }}
  overrideProps={{ style: { overflow: "visible" } }}
/>
<FlashList
  data={items}
  renderItem={renderItem}
  style={{ flex: 1, backgroundColor: '#f5f5f5' }}
/>
contentContainerStyle
StyleProp<ViewStyle>
Style for the internal content container (inherited from ScrollView).
<FlashList
  data={items}
  renderItem={renderItem}
  contentContainerStyle={{ paddingHorizontal: 16 }}
/>
overrideProps
OverrideProps
Allows overriding internal ScrollView props. Props provided here are spread onto the internal ScrollView after all other props, so they take highest priority.This can be useful for cases where you need to set a style on the ScrollView itself rather than the outer container. For example, to enable visible overflow you can combine this with the style prop.
Use with caution — overriding internal props may interfere with FlashList’s layout and recycling behavior.
<FlashList
  data={items}
  renderItem={renderItem}
  style={{ overflow: "visible" }}
  overrideProps={{
    style: { overflow: "visible" },
    showsVerticalScrollIndicator: false,
  }}
/>
Type Definition:
interface OverrideProps {
  initialDrawBatchSize?: number;
  [key: string]: any;
}

Sticky Headers

stickyHeaderIndices
number[]
An array of indices marking items that should stick to the top of the screen when scrolling. Inherited from ScrollView.
<FlashList
  data={items}
  renderItem={renderItem}
  stickyHeaderIndices={[0, 5, 10]}
/>
stickyHeaderConfig
StickyHeaderConfig
Configuration options for sticky headers.
<FlashList
  data={items}
  renderItem={renderItem}
  stickyHeaderIndices={[0]}
  stickyHeaderConfig={{
    useNativeDriver: true,
    offset: 60,
    hideRelatedCell: false,
    backdropComponent: <BlurView />,
  }}
/>
Properties:
  • useNativeDriver (boolean, default: true): If true, the sticky headers will use native driver for animations
  • offset (number, default: 0): Offset from the top of the list where sticky headers should stick. Useful when you have a fixed header or navigation bar at the top of your screen
  • hideRelatedCell (boolean, default: false): When a sticky header is displayed, the cell associated with it is hidden
  • backdropComponent (React.ComponentType | React.ReactElement): Component to render behind sticky headers (e.g., a backdrop or blur effect). Renders in front of the scroll view content but behind the sticky header itself
onChangeStickyIndex
(current: number, previous: number) => void
Callback invoked when the currently displayed sticky header changes. Receives the current sticky header index and the previous sticky header index.This is useful for tracking which header is currently stuck at the top while scrolling. The index refers to the position of the item in your data array that’s being used as a sticky header.
<FlashList
  data={items}
  renderItem={renderItem}
  stickyHeaderIndices={[0, 10, 20]}
  onChangeStickyIndex={(current, previous) => {
    console.log(`Sticky header changed from ${previous} to ${current}`);
  }}
/>

Refresh Control

onRefresh
() => void
If provided, a standard RefreshControl will be added for “Pull to Refresh” functionality. Make sure to also set the refreshing prop correctly.
const [refreshing, setRefreshing] = useState(false);

const onRefresh = async () => {
  setRefreshing(true);
  await fetchNewData();
  setRefreshing(false);
};

<FlashList
  data={items}
  renderItem={renderItem}
  onRefresh={onRefresh}
  refreshing={refreshing}
/>
refreshing
boolean | null | undefined
default:"false"
Set this true while waiting for new data from a refresh.
<FlashList
  data={items}
  renderItem={renderItem}
  onRefresh={onRefresh}
  refreshing={refreshing}
/>
progressViewOffset
number
Set this when offset is needed for the loading indicator to show correctly.
<FlashList
  data={items}
  renderItem={renderItem}
  onRefresh={onRefresh}
  refreshing={refreshing}
  progressViewOffset={100}
/>

Lifecycle Callbacks

onLoad
(info: { elapsedTimeInMs: number }) => void
This event is raised once the list has drawn items on the screen. It also reports elapsedTimeInMs which is the time it took to draw the items.This is required because FlashList doesn’t render items in the first cycle. Items are drawn after it measures itself at the end of first render. If you’re using ListEmptyComponent, this event is raised as soon as ListEmptyComponent is rendered.
<FlashList
  data={items}
  renderItem={renderItem}
  onLoad={({ elapsedTimeInMs }) => {
    console.log(`List loaded in ${elapsedTimeInMs}ms`);
  }}
/>
onCommitLayoutEffect
() => void
Called when the layout is committed. Can be used to measure list.
Doing setState inside the callback can lead to infinite loops. Make sure FlashList’s props are memoized.
<FlashList
  data={items}
  renderItem={renderItem}
  onCommitLayoutEffect={() => {
    console.log('Layout committed');
  }}
/>

Build docs developers (and LLMs) love