ifelsething logoifelsething

Refresh in React Native ScrollView

Published On: 2024-07-11
Posted By: Harish

Refresh in React Native ScrollView

Sometimes we may need to get the fresh updated data from an API to show in a scrollview. We can use a button to get data whenever we manually press the button.

Or we can use RefreshControl of scrollview to get the updated data by pulling down scrollview content when scroll y-axis position is at 0. This functionality only works with vertical scrollview.

Let's see how this refresh 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 which adds a new color block on refresh.

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

Color blocks list can be seen on render.

For this example, we will add a new color red to the list whenever we refresh the scrollview.

For that, we have to import RefreshControl component from react-native and add it to scrollview's refreshControl prop.

The RefreshControl component requires a refreshing prop, which accepts boolean values and is used to show or hide the loading indicator. Another one is the onRefresh callback to call a function to update scrollview data.

...
import { RefreshControl } from 'react-native';
...
<ScrollView
  ...
  refreshControl={
    <RefreshControl
      refreshing={refreshing}
      onRefresh={onRefresh}
    />
  }
>
...
</ScrollView>
...

Please refer to the complete code block below for code.

For refreshing prop, we used useState to store the state of the indicator. And for the onRefresh function, we are updating the colors list with a new one inside a timeout function to delay the process. This timeout function is completely for this tutorial and not needed in general.

If we reload the metro and pull down the list, we can see a loading indicator and after 1 second we will see a new color block added to the list.

Refresh in React Native ScrollView

Change Refresh Indicator Color

We can change the default color of the refresh indicator to our own color. But different props are required for different platforms.

For iOS, tintColor prop and for Android colors prop are to be used.

The tintColor accepts a single color whereas RefreshControl's colors prop accepts an array of colors.

Let's add indicator color for iOS. Add tintColor prop to scrollview with a color. And run the app in an iPhone simulator or device.

If we refresh the scrollview, we will see a green indicator.

Refresh in React Native ScrollView

For Android OS, add colors prop with an array of colors. Longer duration to refresh shows different colors listed in the array.

For this, let's increase the timeout time to 5 Seconds. Add colors prop to scrollview and pull down to refresh in android device or emulator.

...
<ScrollView
  ...
  refreshControl={
    <RefreshControl
      ...
      tintColor='green'
      colors={['blue', 'green', 'red']}
    />
  }
>
...
</ScrollView>
...

We will notice that the indicator changes its color to listed colors till the data refreshes.

Refresh in React Native ScrollView

Change Refresh Indicator Position

If you want to shift the refresh indicator's position, use progressViewOffset prop. This prop accept number to shift the indicator's position vertically.

Complete code of our example,

//App.tsx
import React, { useState, useCallback } from "react";
import {
  Text,
  StyleSheet,
  SafeAreaView,
  StatusBar,
  View,
  ScrollView,
  RefreshControl,
} from "react-native";

let defaultColors = [
  'orange',
  'green',
  'blue',
  'maroon',
  'violet',
  'darkorange',
  'gold',
  'darkgreen',
  'aquamarine',
  'cadetblue'
];

export default function App() {
  const [refreshing, setRefreshing] = useState(false);
  const [colors, setColors] = useState(defaultColors);
  const onRefresh = useCallback(() => {
    setRefreshing(true);
    setTimeout(() => {
      setColors(prev => ["red", ...prev]);
      setRefreshing(false);
    }, 1000);
  }, []);
  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}>
          refresh in scrollview
        </Text>
        <ScrollView
          refreshControl={
            <RefreshControl
              refreshing={refreshing}
              onRefresh={onRefresh}
              //progressViewOffset={10}
            />
          }
          contentContainerStyle={styles.content_container}
        >
          {
            colors.map((color: string, index: number) => {
              return (
                <View
                  key={index}
                  style={[
                    styles.view,
                    {
                      backgroundColor: color
                    }
                  ]}
                />
              )
            })
          }
        </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