Scroll Programmatically in a FlatList
Published On: 2024-09-20
Posted By: Harish

We generally scroll to get to an item of the list. But what if you want to go to a list item without scrolling, like with the press of a button?
In those cases, we can programmatically scroll to an item by using the item itself or its index.
We have seen a way to scroll programmatically with VirtualizedList. As FlatList inherits VirtualizedList props, we can use the same props to programmatically scroll in FlatList using useRef hook.
In this post, we will discuss each scrolling prop with an example. I already covered a detailed post about scrolling programmatically to different list items using these methods which is applicable to this post’s FlatList too.
Create A New Project
Create a new react-native project by using npx. Check documentation for creating a new react native project.
npx react-native@latest init FlatListRN
Example Implementation
We will create a simple vertical FlatList and use different props to get to a list item.
Import FlatList
from react-native and add to App.tsx
file. You can find more info about a basic FlatList by visiting FlatList with a basic example post.
//App.tsx
...
import { FlatList } from 'react-native';
...
<FlatList
contentContainerStyle={styles.content_container}
data={data}
keyExtractor={item => item + ""}
renderItem={({ item }) => {
return (
<Item item={item} />
)
}}
/>
...
If we run the app now,
#for Android
npx react-native run-android
#for ios
npx react-native run-ios
We will see a simple vertical list with their indexes.
Now to scroll to different items, we have scrollToIndex(), scrollToItem(), scrollToOffset() and scrollToEnd() methods.
To use these methods, we have to use the useRef() hook to get the reference of the FlatList and to call these methods.
So, lets import useRef hook from react and get the reference of this list.
...
import React, { useRef } from 'react';
...
const ref = useRef(null);
....
<FlatList
...
ref={ref}
/>
...
We got the reference to call scroll methods.
scrollToIndex()
For the first method, let's see the use of the scrollToIndex()
method.
As the name says, this method can be used to scroll to an item based on its index.
Let's add a button and on the button press, the list has to scroll to an item with index 5
.
So import a Button component and on press call scrollToIndex() method with index five.
This method accepts index and other properties which I already covered in my programmatically scroll to list items in react native post. Please check that post for more info.
...
<Button
title="index(5)"
onPress={() => listRef.current.scrollToIndex({ index: 5 })}
/>
....
Now, if we press the button, the list automatically scrolls to an item with index five.
scrollToItem()
What if you don't have the index of an item but the item itself?
In those cases, we can use the scrollToItem()
method which accepts the direct item of the list to be scrolled to.
Again add a button and use this method to scroll to the third item.
...
<Button
title="item(3rd)"
onPress={() => listRef.current.scrollToItem({ item: data[2] })}
/>
....
scrollToOffset()
Now, what if you don't have either an index or the item but have the height of an item?
In those cases, we can use the scrollToOffset()
method, which accepts an offset, in other words, accepts the total height to scroll in a vertical list and total width to be scrolled to when the list is horizontal.
Please refer to start scroll from different positions post for more info.
And also note that, we are using a vertical list, so we are using the height of the item as all the items have the same height.
If we have different heights and widths, this scrollToOffset() method will not work properly to scroll to an item. Instead, check scroll to react native list items with different heights and widths post for more info on scrolling programmatically when items have different heights.
...
<Button
title="offset(1470)"
onPress={() => listRef.current.scrollToOffset({ offset: 1400 + 70 })}
/>
....
Here we are scrolling to the 8th item which is having seven as index.
Each item has the same height of 200
and we have to scroll seven items to reach the 8th item. So, its 200 * 7 = 1400
to scroll.
We have an additional gap of 10
for each item. So, 10 * 7 = 70
.
So, we have to scroll till 1400 + 70
y-axis point to reach 8th item.
scroll to starting position (scrollToOffset(0))
To scroll to the start of the list, we can use scrollToOffset() method with (0, 0)
or simply 0
.
...
<Button
title="start"
onPress={() => listRef.current.scrollToOffset(0)}
/>
....
scrollToEnd()
With the scrollToEnd() method, we can automatically scroll to the end of the list by directly calling it.
...
<Button
title="end"
onPress={() => listRef.current.scrollToEnd()}
/>
....
In this way we can scroll to different items programmatically.

Complete code of our example,
//App.tsx
import React, { useRef } from "react";
import {
Text,
StyleSheet,
SafeAreaView,
StatusBar,
View,
FlatList,
Button
} from "react-native";
export default function App() {
const data = [...Array(10).keys()];
const listRef = useRef(null);
const Item = ({ item }: { item: number }) => {
return (
<View
key={item}
style={styles.item_view}
>
<Text style={styles.item_text}>{item}</Text>
</View>
)
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>
<StatusBar
barStyle="dark-content"
/>
<View style={styles.container}>
<Text style={styles.text}>
ifelsething.com
</Text>
<Text style={styles.text}>
scroll programmatically in a FlatList
</Text>
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
}}
>
<Button
title="start"
onPress={() => listRef.current.scrollToOffset(0)}
/>
<Button
title="index(5)"
onPress={() => listRef.current.scrollToIndex({ index: 5 })}
/>
<Button
title="item(3rd)"
onPress={() => listRef.current.scrollToItem({ item: data[2] })}
/>
<Button
title="offset(1470)"
onPress={() => listRef.current.scrollToOffset({ offset: 1400 + 70 })}
/>
<Button
title="end"
onPress={() => listRef.current.scrollToEnd()}
/>
</View>
<FlatList
ref={listRef}
contentContainerStyle={styles.content_container}
data={data}
keyExtractor={item => item + ""}
renderItem={({ item }) => {
return (
<Item item={item} />
)
}}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 10,
gap: 20
},
text: {
fontSize: 15,
color: 'black',
fontStyle: 'italic'
},
content_container: {
gap: 10
},
item_view: {
width: '100%',
height: 200,
borderRadius: 10,
backgroundColor: 'purple',
alignItems: 'center',
justifyContent: 'center'
},
item_text: {
color: 'white',
fontSize: 30,
}
});