Implementing Pull-to-Refresh in React Native

Pull-to-refresh is a common gesture in mobile applications that allows users to update content by pulling down on the screen.

July 19, 20243 min read

Pull-to-refresh is a common gesture in mobile applications that allows users to update content by pulling down on the screen. In React Native, this functionality is easy to implement using built-in components. This article will guide you through implementing pull-to-refresh in various scenarios.

Basic Pull-to-Refresh with FlatList

The FlatList component in React Native has built-in support for pull-to-refresh. Here's how to implement it:

import React, { useState, useCallback } from 'react';
import { FlatList, Text, View, StyleSheet } from 'react-native';

const BasicPullToRefresh = () => {
  const [data, setData] = useState([
    { id: '1', title: 'Item 1' },
    { id: '2', title: 'Item 2' },
    { id: '3', title: 'Item 3' },
  ]);
  const [refreshing, setRefreshing] = useState(false);

  const onRefresh = useCallback(() => {
    setRefreshing(true);
    // Simulate fetching new data
    setTimeout(() => {
      setData([
        { id: '4', title: 'New Item 1' },
        { id: '5', title: 'New Item 2' },
        ...data,
      ]);
      setRefreshing(false);
    }, 2000);
  }, [data]);

  const renderItem = ({ item }) => (
    <View style={styles.item}>
      <Text>{item.title}</Text>
    </View>
  );

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      refreshing={refreshing}
      onRefresh={onRefresh}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
    backgroundColor: '#f9c2ff',
  },
});

export default BasicPullToRefresh;

In this example:

  • We use the refreshing prop to control the refresh state.
  • The onRefresh prop is a callback that's triggered when the user pulls to refresh.
  • Inside onRefresh, we set refreshing to true, fetch new data (simulated with a timeout), update the state, and set refreshing back to false.

Pull-to-Refresh with ScrollView

For simpler lists or custom layouts, you might want to use ScrollView instead of FlatList. Here's how to implement pull-to-refresh with ScrollView:

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

const ScrollViewPullToRefresh = () => {
  const [refreshing, setRefreshing] = useState(false);

  const onRefresh = useCallback(() => {
    setRefreshing(true);
    // Simulate fetching new data
    setTimeout(() => {
      setRefreshing(false);
    }, 2000);
  }, []);

  return (
    <ScrollView
      contentContainerStyle={styles.scrollView}
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }
    >
      <Text style={styles.text}>Pull down to refresh</Text>
      {/* Your ScrollView content goes here */}
    </ScrollView>
  );
};

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

export default ScrollViewPullToRefresh;

Here, we use the RefreshControl component wrapped in the refreshControl prop of ScrollView to add pull-to-refresh functionality.

Try Kodaschool for free

Click below to sign up and get access to free web, android and iOs challenges.

Sign Up

Customizing the Refresh Control

You can customize the appearance of the refresh control:

<RefreshControl
  refreshing={refreshing}
  onRefresh={onRefresh}
  colors={['#0000ff', '#ff00ff']} // Android
  tintColor="#00ff00" // iOS
  title="Refreshing..." // iOS
  titleColor="#00ff00" // iOS
/>

Implementing Pull-to-Refresh with APIs

In real-world applications, you'll typically fetch data from an API when refreshing. Here's an example using the fetch API:

import React, { useState, useCallback } from 'react';
import { FlatList, Text, View, StyleSheet } from 'react-native';

const ApiPullToRefresh = () => {
  const [data, setData] = useState([]);
  const [refreshing, setRefreshing] = useState(false);

  const fetchData = async () => {
    const response = await fetch('https://api.example.com/data');
    const newData = await response.json();
    setData(newData);
  };

  const onRefresh = useCallback(() => {
    setRefreshing(true);
    fetchData().then(() => setRefreshing(false));
  }, []);

  const renderItem = ({ item }) => (
    <View style={styles.item}>
      <Text>{item.title}</Text>
    </View>
  );

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      refreshing={refreshing}
      onRefresh={onRefresh}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
    backgroundColor: '#f9c2ff',
  },
});

export default ApiPullToRefresh;

In this example, fetchData is an async function that fetches data from an API. The onRefresh function calls fetchData and updates the refreshing state accordingly.

Best Practices

  • Keep it quick: Aim to complete the refresh operation as quickly as possible. If it takes too long, consider showing a loading indicator elsewhere in your UI.
  • Handle errors: Make sure to handle potential errors during the refresh operation and communicate them to the user if necessary.
  • Don't abuse it: Only use pull-to-refresh for actually refreshing content. Don't use it for other operations that might confuse users.
  • Consistent behaviour: Ensure that pull-to-refresh behaviour is consistent across your app where it's implemented.
  • Visual feedback: Always provide clear visual feedback when the refresh is in progress and when it is completed.

Pull-to-refresh is a powerful and intuitive way to allow users to update content in your React Native application. By leveraging built-in components like FlatList and RefreshControl, you can easily implement this feature in your apps. Remember to consider the user experience, handle errors gracefully, and follow platform-specific design guidelines for the best results.

Cliff Gor

About Cliff Gor

As a Fullstack Software Engineer, I design and develop user-centric and robust systems and applications using HTML, CSS, Bootstrap, React Js, React Native, and Kotlin(Android).