ifelsething logoifelsething

Scroll Programmatically in React Native

Published On: 2024-06-26
Posted By: Harish

Scroll Programmatically in React Native

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.

Scroll Programmatically in React Native

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"
/>
...
Scroll Programmatically in React Native

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"
/>
...
Scroll Programmatically in React Native

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
  }
});

Share is Caring

Related Posts