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,
};
};
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]);
};
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>
);
}
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>;
}
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} />);
}
How It Works
- User pulls down the screen
- triggerRefresh runs
- All registered functions run at the same time
- Spinner shows while loading
- 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)