Add pull to refresh in React Native using RefreshControl

Introduction :

React native provides one component to add pull to refresh functionality called RefreshControl. You can use it with a ScrollView or ListView. We need to manually change the state of this component. It calls one function when the refresh starts and we need to manually set it as true to make it appear. Next, once everything i.e. refresh is done, we need to set it as false to make it stop.

It provides a couple of props that I am listing down first before showing you how it works :

Props of RefreshControl :

1. refreshing :

This is a boolean value to indicate if the refresh is active or not.

2. onRefresh :

This is a function that calls when the view starts refreshing. Once it is called, we need to mark refreshing as true to show the component.

3. colors :

It is an array of colors that will be used for the refresh indicator. It is available only on Android.

4. enabled :

Only for Android. It is a boolean value to define whether this functionality is enabled or not.

5. progressBackgroundColor :

Only for Android. The background color of the progress indicator.

6. progressViewOffset :

Top offset of the progress view.

7. size :

It is an enum value. It can take any one of the RefreshLayoutConsts.SIZE.DEFAULT, RefreshLayoutConsts.SIZE.LARGE. It is available only for android.

8. tintColor :

Color of the refresh indicator. Available for iOS.

9. title and titleColor :

Available only on iOS. These are used for title and color of the title respectively.

Example :

I am using the default react native project where App.js holds everything :

import React, {useState, useCallback} from 'react';
import {
  SafeAreaView,
  StatusBar,
  StyleSheet,
  RefreshControl,
  ScrollView,
  Text,
} from 'react-native';

function delay(timeout) {
  return new Promise(resolve => {
    setTimeout(resolve, timeout);
  });
}

const App = () => {
  const [loading, setLoading] = useState(false);

  const loadMore = useCallback(async () => {
    setLoading(true);

    delay(1500).then(() => setLoading(false));
  }, [loading]);

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={styles.container}>
        <ScrollView
          contentContainerStyle={styles.scrollView}
          refreshControl={
            <RefreshControl
              progressBackgroundColor="red"
              tintColor="red"
              refreshing={loading}
              onRefresh={loadMore}
            />
          }>
          <Text>Swipe down to refresh</Text>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

If you run it, it will produce one result like below :

react native refreshcontrol

We are using one delay here. We can load the data during this time like making an API call.

The props work differently on both android and iOS. Make sure to test it on both platforms