Scroll Programmatically in React Native
Published On: 2024-06-26
Posted By: Harish

We can touch and drag to scroll a list in a scrollview. But what if we want to scroll programmatically to a position without dragging?
For that, we can use scrollview's scrollTo() and scrollToEnd() methods to scroll programmatically.
Let's see how this scroll works with an example.
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 ScrollViewRN
Example Implementation
We will create a simple vertical scrollview with color blocks and scroll to different blocks using the above mentioned methods.
Import and add ScrollView
with few scrollable color blocks.
//App.tsx
...
import { View, ScrollView } from 'react-native';
...
<ScrollView
contentContainerStyle={styles.content_container}
>
{
colors
.map((color: string) => {
return (
<View
key={color}
style={[
styles.view,
{
backgroundColor: color
}
]}
>
</View>
)
})
}
</ScrollView>
...
If we run the app,
#for Android
npx react-native run-android
#for ios
npx react-native run-ios
We will see a few scrollable color blocks list.
So, for this example, we will scroll to the fourth block using the scrollTo()
method on click of a button.
To get the scrollview methods, first we have to get the scrollview’s reference using the useRef
hook and call these methods using the reference.
Lets import useRef hook from react and set the reference to scrollview. Also import the Button
component and call scroll methods on click of the button.
...
const ref = useRef<ScrollView>(null);
...
<Button
onPress={() => ref.current?.scrollTo({y: 630, animated: true})}
title="Scroll To Fourth Block"
/>
...
<ScrollView
...
ref={ref}
>
...
</ScrollView>
...
Now the main question is, how I got the number 630
? Also why did I use the y
axis and not the x
axis?.
First visualize the screen in x and y axis dimensions from scrollview's starting point. As we have a vertical scrollview, we will scroll along the y-axis and that's the reason for using y
number.
If you have a horizontal list, then use the x
number.
Now, each block's height is 200
with a gap of 10
each. So, to go to the fourth block, we have to scroll three blocks down through the y-axis
, resulting in a total height of 630
. You can find the styles from the complete code section.
Now reload the metro builder and press the button to automatically scroll to the fourth block.

Go to End Position
If you want to go to the end of the scrollview, we can use the scrollToEnd()
method. This method does not need any coordinates.
Simply call the method and it will just go to the end.
...
<Button
onPress={() => ref.current?.scrollToEnd()}
title="Scroll To End"
/>
...

Go to Starting Position
We don't have any default method to scroll to top of the scrollview. For this, we have to use the scrollTo()
method again.
Instead of passing the height or width values of items, we have to pass the coordinates of the scrollview starting position and that is {x: 0, y: 0}
.
Irrespective of the scroll direction, using both coordinates is better. If not, you can use the required coordinate based on the scroll view direction.
...
<Button
onPress={() => ref.current?.scrollTo({ x: 0, y: 0, animated: true })}
title="Scroll To Start"
/>
...

Complete code of our example,
//App.tsx
import React, { useRef } from "react";
import {
Text,
StyleSheet,
SafeAreaView,
StatusBar,
View,
ScrollView,
Button,
} from "react-native";
const colors = [
'orange',
'green',
'blue',
'maroon',
'violet',
'darkorange',
'gold',
'darkgreen',
'aquamarine',
'cadetblue'
];
export default funtion App() {
const ref = useRef<ScrollView>(null);
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
</Text>
<Button
onPress={() => ref.current?.scrollTo({ y: 630, animated: true })}
title="Scroll To Fourth Block"
/>
{/* <--Other scroll positions-->
<Button
onPress={() => ref.current?.scrollToEnd()}
title="Scroll To End"
/>
<Button
onPress={() => ref.current?.scrollTo({ x: 0, y: 0, animated: true })}
title="Scroll To Start"
/> */}
<ScrollView
ref={ref}
contentContainerStyle={styles.content_container}
>
{
colors
.map((color: string) => {
return (
<View
key={color}
style={[
styles.view,
{
backgroundColor: color
}
]}
>
</View>
)
})
}
</ScrollView>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 10,
gap: 20
},
text: {
fontSize: 15,
color: 'black',
fontStyle: 'italic'
},
content_container: {
gap: 10
},
view: {
width: '100%',
height: 200,
borderRadius: 10
}
});