Skip to main content
This component is used inside a ScrollView or ListView to add pull to refresh functionality. When the ScrollView is at scrollY: 0, swiping down triggers an onRefresh event.

Example

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

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

  const onRefresh = () => {
    setRefreshing(true);
    // Simulate a network request
    setTimeout(() => {
      setRefreshing(false);
    }, 2000);
  };

  return (
    <ScrollView
      contentContainerStyle={styles.scrollView}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
        />
      }
    >
      <Text>Pull down to refresh</Text>
    </ScrollView>
  );
};

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

export default App;

Props

refreshing
boolean
required
Whether the view should be indicating an active refresh.Note: refreshing is a controlled prop, this is why it needs to be set to true in the onRefresh function otherwise the refresh indicator will stop immediately.
onRefresh
() => void | Promise<void>
Called when the view starts refreshing.
progressViewOffset
number
Progress view top offset.

iOS-Specific Props

tintColor
ColorValue
The color of the refresh indicator.Platform: iOS
title
string
The title displayed under the refresh indicator.Platform: iOS
titleColor
ColorValue
The color of the refresh indicator title.Platform: iOS

Android-Specific Props

colors
Array<ColorValue>
The colors (at least one) that will be used to draw the refresh indicator.Platform: Android
enabled
boolean
default:true
Whether the pull to refresh functionality is enabled.Platform: Android
progressBackgroundColor
ColorValue
The background color of the refresh indicator.Platform: Android
size
'default' | 'large'
Size of the refresh indicator.Platform: Android

Usage with FlatList

import React, { useState } from 'react';
import { FlatList, RefreshControl, Text } from 'react-native';

const App = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [data, setData] = useState(['Item 1', 'Item 2', 'Item 3']);

  const onRefresh = () => {
    setRefreshing(true);
    // Fetch new data
    fetchNewData().then(newData => {
      setData(newData);
      setRefreshing(false);
    });
  };

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text>{item}</Text>}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
          colors={['#ff0000', '#00ff00', '#0000ff']}
          tintColor="#ff0000"
        />
      }
    />
  );
};

Platform Differences

iOS

  • Shows a spinner-style refresh indicator
  • Supports custom color via tintColor
  • Can display a title below the spinner
  • Smooth animation that follows the pull gesture

Android

  • Shows a Material Design circular progress indicator
  • Supports multiple colors via colors array
  • Can set background color via progressBackgroundColor
  • Has two size options: 'default' and 'large'
  • Can be disabled via enabled prop

Important Notes

  • The refreshing prop must be set to true in the onRefresh callback for the refresh indicator to show
  • Remember to set refreshing back to false when the refresh operation completes
  • The RefreshControl must be used as a child of a ScrollView, FlatList, or SectionList
  • On iOS, the refresh control appears when you pull down from scrollY: 0
  • The onRefresh callback can return a Promise for async operations

Controlled Component Pattern

RefreshControl is a controlled component, meaning you must manage the refreshing state:
const [refreshing, setRefreshing] = useState(false);

const onRefresh = async () => {
  setRefreshing(true);
  try {
    await fetchData();
  } finally {
    setRefreshing(false);
  }
};

Build docs developers (and LLMs) love