DEV Community

Cover image for How to Build a Global Refresh System in React Native
Karim Mohammadi
Karim Mohammadi

Posted on

How to Build a Global Refresh System in React Native

Introduction

Do you want to refresh many components at once in React Native? This guide shows you how. We will build a simple refresh system. When a user pulls down the screen, all data updates together.

The Problem

Imagine your app has many parts:

  • A user profile section
  • A news feed section
  • A notifications section

Each part has its own data. When the user pulls to refresh, you want ALL parts to update. How do you do this?

The Solution: Refresh Context

We use React Context. Context lets components share data. Our context will share refresh functions.

Step 1: Create the Refresh Context

import React, { useCallback, useState } from "react";

export const useRefreshControls = () => {
  const [isRefreshing, setIsRefreshing] = useState(false);
  const refreshFunctions = React.useRef(new Map());

  const registerRefreshHandler = useCallback((id, refreshFn) => {
    refreshFunctions.current.set(id, refreshFn);
  }, []);

  const unregisterRefreshHandler = useCallback((id) => {
    refreshFunctions.current.delete(id);
  }, []);

  const triggerRefresh = useCallback(async () => {
    setIsRefreshing(true);
    try {
      const promises = Array.from(refreshFunctions.current.values())
        .map((fn) => fn());
      await Promise.all(promises);
    } finally {
      setIsRefreshing(false);
    }
  }, []);

  return {
    isRefreshing,
    triggerRefresh,
    registerRefreshHandler,
    unregisterRefreshHandler,
  };
};
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a Subscribe Hook

This hook lets components register their refresh function.

export const useSubscribeToRefresh = (id, refreshFn) => {
  const { registerRefreshHandler, unregisterRefreshHandler } = useRefreshContext();

  React.useEffect(() => {
    registerRefreshHandler(id, refreshFn);
    return () => unregisterRefreshHandler(id);
  }, [id, refreshFn]);
};
Enter fullscreen mode Exit fullscreen mode

Step 3: Set Up the Provider

Wrap your app with the provider.

function App() {
  const refreshControls = useRefreshControls();

  return (
    <RefreshProvider value={refreshControls}>
      <ScrollView
        refreshControl={
          <RefreshControl
            refreshing={refreshControls.isRefreshing}
            onRefresh={refreshControls.triggerRefresh}
          />
        }
      >
        <UserProfile />
        <NewsFeed />
      </ScrollView>
    </RefreshProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Use in Components

Each component registers its own refresh function.

function UserProfile() {
  const [user, setUser] = useState(null);

  const fetchUser = async () => {
    const data = await api.getUser();
    setUser(data);
  };

  useSubscribeToRefresh("user-profile", fetchUser);

  return <Text>{user?.name}</Text>;
}
Enter fullscreen mode Exit fullscreen mode
function NewsFeed() {
  const [posts, setPosts] = useState([]);

  const fetchPosts = async () => {
    const data = await api.getPosts();
    setPosts(data);
  };

  useSubscribeToRefresh("news-feed", fetchPosts);

  return posts.map((post) => <PostCard key={post.id} post={post} />);
}
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. User pulls down the screen
  2. triggerRefresh runs
  3. All registered functions run at the same time
  4. Spinner shows while loading
  5. Spinner hides when all data is ready

Benefits

  • Simple: Easy to add to any component
  • Fast: All requests run in parallel
  • Clean: Components manage their own data
  • Automatic: Cleanup happens when components unmount

Conclusion

This pattern makes pull-to-refresh easy in React Native. Each component registers its refresh function. One pull updates everything. Your users get fresh data fast.

Top comments (0)