Props
Below is a list of all the properties for LegendList:
Required Props
data
data: ItemT[];
An array of the items to render. This can also be an array of keys if you want to get the item by key in renderItem.
renderItem
renderItem?: (props: LegendListRenderItemProps<ItemT>) => ReactNode;
Takes an item from data and renders it into the list.
See React Native Docs.
Recommended Props
keyExtractor
keyExtractor?: (item: ItemT, index: number) => string;
Highly recommended. The keyExtractor
prop lets Legend List save item layouts by key, so that if the data
array changes it can reuse previous layout information and only update the changed items. The value it returns should be unique to each item - if a value is reused for a different item it will cause big problems. It is okay to return the index, if list items are reordered or prepended, it will also cause big problems. See Use key extractor.
If LegendList detects duplicate keys, it will log a warning.
recycleItems
recycleItems?: boolean; // default: false
This will reuse the component rendered by your renderItem
function. This can be a big performance improvement, but if your list items have internal state there’s potential for undesirable behavior. For more information, see Performance for more information.
estimatedItemSize
estimatedItemSize?: number;
An estimated size for all items which is used to estimate the list layout before items actually render. This can help to provide a hint for how large items will be in the first frame and can speed up initial layout, but subsequent renders will use the average item size.
Optional Props
alignItemsAtEnd
alignItemsAtEnd?: boolean; // default: false
Aligns to the end of the screen. If there’s only a few items, Legend List will add padding to the top to align them to the bottom. See Chat interfaces without inverse for more.
columnWrapperStyle
columnWrapperStyle?: StyleProp<ViewStyle>;
Style applied to each column’s wrapper view.
contentContainerStyle
contentContainerStyle?: StyleProp<ViewStyle>;
Style applied to the underlying ScrollView’s content container.
drawDistance
drawDistance?: number;
The drawDistance
(defaults to 250
) is the buffer size in pixels above and below the viewport that will be rendered in advance. See Performance for more.
extraData
extraData?: any;
Extra data to trigger re-rendering when changed.
See React Native Docs.
getEstimatedItemSize
getEstimatedItemSize?: (index: number, item: ItemT) => number;
An estimated size for each item which is used to estimate the list layout before items actually render. If you don’t provide this, it will log a suggested value for optimal performance.
horizontal
horizontal?: boolean; // default: false
Renders all items in the list in horizontal.
initialContainerPoolRatio
initialContainerPoolRatio?: number; // default: 2
Ratio of initial container pool size to data length. The container pool is extra unallocated containers that are used in case the actual size is smaller than the estimated size. This defaults to 2
which we’ve found to cover most usage. If your items are a fixed size you could set it closer to 1
, or if your items or viewport can resize signficantly it may help to increase it. If the number of containers needed exceeds the pool, LegendList will allocate more containers and re-render the outer list, which may cause a frame stutter.
initialScrollIndex
initialScrollIndex?: number;
Start scrolled with this item at the top. By default, to have accurate scrolling position you will need to provide accurate element positions to the getEstimatedItemSize function(similar FlatList). When accurate positions are not known (e.g., for dynamically sized list items), please enable maintainVisibleContentPosition prop. This will allow LegendList to automatically adjust its top boundary when elements below initialScrollIndex will be measured.
initialScrollOffset
initialScrollOffset?: number;
Start scrolled to this offset.
ItemSeparatorComponent
ItemSeparatorComponent?: React.ComponentType<{ leadingItem: ItemT }>
Rendered in between each item, but not at the top or bottom.
See React Native Docs.
ListEmptyComponent
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
Rendered when the list is empty.
See React Native Docs.
ListEmptyComponentStyle
ListEmptyComponentStyle?: StyleProp<ViewStyle> | undefined;
Styling for internal View for ListEmptyComponent
.
ListFooterComponent
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
Rendered at the bottom of all the items.
See React Native Docs.
ListFooterComponentStyle
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
Styling for internal View for ListFooterComponent
.
See React Native Docs.
ListHeaderComponent
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
Rendered at the top of all the items.
See React Native Docs.
ListHeaderComponentStyle
Styling for internal View for ListHeaderComponent
.
See React Native Docs.
maintainScrollAtEnd
maintainScrollAtEnd?: boolean;
This will check if you are already scrolled to the bottom when data
changes, and if so it keeps you scrolled to the bottom.
See Chat interfaces without inverted
for more.
maintainScrollAtEndThreshold
maintainScrollAtEndThreshold?: number;
This defines what percent of the screen counts as the bottom. Defaults to 0.1
.
See Chat interfaces without inverted
for more.
maintainVisibleContentPosition
maintainVisibleContentPosition?: boolean;
The maintainVisibleContentPosition
prop automatically adjusts item positions when items are added/removed/resized above the viewport so that there is no shift in the visible content. This is very helpful for some scenarios, but if you have a static list of fixed sized items you probably don’t need it.
- If items get added/removed/resized above the viewport, items will not move on screen
- When using
initialScrollOffset
orinitialScrollIndex
, items will not jump around when scrolling up if they’re different sizes than the estimate - When scrolling to an index far down the list and then back up, items will not jump around as they layout
LegendList utilizes ScrollView’s maintainVisibleContentPosition prop internally, so your target react-native version should support that prop. To use maintainVisibleContentPosition on Android you will need at least React Native version 0.72.
numColumns
numColumns?: number;
Multiple columns will zig-zag like a flexWrap layout. Rows will take the maximum height of their columns, so items should all be the same height - masonry layouts are not supported.
onEndReached
onEndReached?: ((info: { distanceFromEnd: number }) => void) | null | undefined;
A callback that’s called only once when scroll is within onEndReachedThreshold
of the bottom of the list. It resets when scroll goes above the threshold and then will be called again when scrolling back into the threshold.
onEndReachedThreshold
onEndReachedThreshold?: number | null | undefined;
The distance from the end as a percentage that the scroll should be from the end to trigger onEndReached
. It is multiplied by screen size, so a value of 0.5 will trigger onEndReached
when scrolling to half a screen from the end.
onItemSizeChanged
onItemSizeChanged?: (info: { size: number; previous: number; index: number; itemKey: string; itemData: ItemT; }) => void;
Called whenever an item’s rendered size changes. This can be used to adjust the estimatedItemSize to match the actual size, which can improve performance or reduce layout shifting.
onRefresh
onRefresh?: () => void;
Called whenever a user pulls down to refresh. See React Native Docs.
onStartReached
onStartReached?: ((info: { distanceFromStart: number }) => void) | null | undefined;
A callback that’s called only once when scroll is within onStartReachedThreshold
of the top of the list. It resets when scroll goes below the threshold and then will be called again when scrolling back into the threshold.
onStartReachedThreshold
onStartReachedThreshold?: number | null | undefined;
The distance from the start as a percentage that the scroll should be from the end to trigger onStartReached
. It is multiplied by screen size, so a value of 0.5 will trigger onStartReached
when scrolling to half a screen from the start.
onViewableItemsChanged
onViewableItemsChanged?: OnViewableItemsChanged | undefined;
Called when the viewability of rows changes, as defined by the viewabilityConfig
prop.
See React Native Docs.
progressViewOffset
progressViewOffset?: number | undefined;
Offset in pixels for the refresh indicator.
ref
ref?: LegendListRef;
Used to call scrollTo
methods.
refreshing
refreshing?: boolean;
Set this true while waiting for new data from a refresh.
See React Native Docs.
renderScrollComponent
renderScrollComponent?: (props: ScrollViewProps) => ReactNode
Render a custom ScrollView component. This allows customization of the underlying ScrollView.
Note that passing renderScrollComponent
as an inline function might cause you to lose scroll position if the list is rerendered.
renderScrollComponent={(props) => <BottomSheetScrollView {...props} />}
Instead, it’s better to extract it as a custom component.
const CustomScrollView = (props: ScrollViewProps) => { return <BottomSheetScrollView {...props} />;};
style
style?: StyleProp<ViewStyle>;
Style applied to the underlying ScrollView.
viewabilityConfig
viewabilityConfig?: ViewabilityConfig;
Configuration for when to update the onViewableItemsChanged
callback.
See React Native Docs.
viewabilityConfigCallbackPairs
viewabilityConfigCallbackPairs?: ViewabilityConfigCallbackPairs | undefined;
List of ViewabilityConfig
/onViewableItemsChanged
pairs. A specific onViewableItemsChanged
will be called when its corresponding ViewabilityConfig
’s conditions are met.
See React Native Docs.
waitForInitialLayout
waitForInitialLayout?: boolean; // default false
If true, delays rendering until initial layout is complete
Ref Methods
getState
getState: () => { contentLength: number; end: number; endBuffered: number; isAtEnd: boolean; isAtStart: boolean; scroll: number; scrollLength: number; start: number; startBuffered: number;}
Returns the internal scroll state of the list.
scrollToIndex
scrollToIndex: (params: { index: number; animated?: boolean;});
Scrolls to the item at the specified index. By default (maintainVisibleContentPosition is false), accurate scroll is guaranteed only if all accurate sizes of elements are provided to getEstimatedItemSize function(similar FlatList).
If estimated item sizes are not known, maintainVisibleContentPosition prop need to be set to true. In this mode, list would automatically select element you are scrolling to as anchor element and guarantee accurate scroll.
scrollToOffset
scrollToOffset(params: { offset: number; animated?: boolean;});
Scroll to a specific content pixel offset in the list.
Valid parameters:
- offset (number) - The offset to scroll to. In case of horizontal being true, the offset is the x-value, in any other case the offset is the y-value. Required.
- animated (boolean) - Whether the list should do an animation while scrolling. Defaults to true.
scrollToItem
scrollToItem(params: { animated?: ?boolean, item: Item,});
Requires linear scan through data - use scrollToIndex instead if possible. Provided for compatibility with FlatList only.
Valid parameters:
- animated (boolean) - Whether the list should do an animation while scrolling. Defaults to true.
- item (object) - The item to scroll to. Required.
scrollToEnd
scrollToEnd(params?: { animated?: boolean,});
Scrolls to the end of the list.
Valid parameters:
- animated (boolean) - Whether the list should do an animation while scrolling. Defaults to true.
scrollIndexIntoView
Scrolls the index into view. If the index is above the viewable range it will be scrolled to the top of the screen, and if it’s below the viewable range it will be scrolled to the bottom of the screen.
scrollIndexIntoView(params: { animated?: boolean | undefined; index: number;}): void
import { LegendList } from "@legendapp/list";import { useRef } from "react";
export function ScrollExample() { const listRef = useRef(null);
const scrollToItem = () => { // Scroll to the item at index 10 listRef.current?.scrollIndexIntoView(10); };
return ( <> <Button title="Scroll to item 10" onPress={scrollToItem} /> <LegendList ref={listRef} data={data} renderItem={renderItem} /> </> );}
scrollItemIntoView
Scrolls the item into view. If the item is above the viewable range it will be scrolled to the top of the screen, and if it’s below the viewable range it will be scrolled to the bottom of the screen.
scrollItemIntoView(params: { animated?: boolean | undefined; item: any;}): void;
import { LegendList } from "@legendapp/list";import { useRef } from "react";
export function ScrollToItemExample() { const listRef = useRef(null); const targetItem = { id: "item-5", text: "Target Item" };
const scrollToSpecificItem = () => { // Scroll to the item that matches targetItem listRef.current?.scrollItemIntoView(targetItem); };
return ( <> <Button title="Scroll to target item" onPress={scrollToSpecificItem} /> <LegendList ref={listRef} data={data} renderItem={renderItem} /> </> );}
Hooks
useRecyclingState
interface LegendListRecyclingState<T> { item: T; prevItem: T | undefined; index: number; prevIndex: number | undefined;}useRecyclingState: <T>(updateState: ((info: LegendListRecyclingState<T>) => T) | T) => [T, Dispatch<T>];
useRecyclingState
automatically resets the state when an item is recycled into a new item.
import { useRecyclingState } from "@legendapp/list"export function ItemComponent({ item }) { // Like useState but it resets when the item is recycled const [isExpanded, setIsExpanded] = useRecyclingState(() => false);
// ...}
useRecyclingEffect
interface LegendListRecyclingState<T> { item: T; prevItem: T | undefined; index: number; prevIndex: number | undefined;}useRecyclingEffect: <T>(effect: (info: LegendListRecyclingState<T>) => void | (() => void)) => void;
useRecyclingEffect
can be used to reset any side effects when an item gets recycled.
import { useRecyclingEffect } from "@legendapp/list"
export function ItemComponent({ item, useRecyclingEffect }) { // A callback when the item is recycled into a new item useRecyclingEffect(({ item, prevItem, index, prevIndex }) => { // Reset any side effects from the previous item refSwipeable?.current?.close(); refVideo?.current?.reset(); });
// ...}
useViewability
interface ViewToken<ItemT = any> { containerId: number; index: number; isViewable: boolean; item: ItemT; key: string;}useViewability: (configId: string, callback: (viewToken: ViewToken) => void) => void;
A hook that provides callbacks when an item’s viewability changes. This hook registers a callback that will be invoked whenever the item’s visibility status changes, providing detailed information about the item through the ViewToken interface. It is similar to onViewableItemsChanged but runs for only the rendering item. If you defined multiple viewability configs using viewabilityConfigCallbackPairs then provide the id of the one you’re interested in with configId
.
import { useViewability } from "@legendapp/list"
export function ItemComponent({ item }) { const [isVisible, setIsVisible] = useState(false);
useViewability((viewToken) => { // Called when viewability changes setIsVisible(viewToken.isViewable);
if (viewToken.isViewable) { console.log("Item visible:", viewToken.item); console.log("Item index:", viewToken.index); } }, "main");
return ( <View> {isVisible ? <ExpensiveComponent /> : <PlaceholderComponent />} </View> );}
useViewabilityAmount
interface ViewAmountToken<ItemT = any> { containerId: number; index: number; isViewable: boolean; item: ItemT; key: string; percentOfScroller: number; percentVisible: number; scrollSize: number; size: number; sizeVisible: number;}
useViewabilityAmount: (callback: (viewAmountToken: ViewAmountToken) => void) => void;
A hook that provides detailed metrics about how much of an item is visible in the viewport. The callback receives a ViewAmountToken with information like the pixel measurements (sizeVisible, size), percentage visible, and more.
import { useViewabilityAmount } from "@legendapp/list"
export function ItemComponent({ item }) { const [opacity, setOpacity] = useState(0);
useViewabilityAmount((viewAmountToken) => { // Get detailed visibility information setOpacity(viewAmountToken.percentVisible);
// Additional metrics available: // viewAmountToken.sizeVisible - pixels of item visible in viewport // viewAmountToken.size - total size of the item // viewAmountToken.percentOfScroller - what percent of the scroller this item takes up // viewAmountToken.scrollSize - size of the viewport });
return ( <Animated.View style={{ opacity }}> <Text>{item.title}</Text> </Animated.View> );}