React Native 0.62.2中Unsplash API图片缓存实现需求问询
Hey there! Let's get this full caching setup working for your Unsplash image search in React Native 0.62.2. I've broken this down into practical, step-by-step parts so you can implement it without hassle.
1. Install Required Dependencies
First, we'll need two core libraries to handle local file storage and metadata persistence. Make sure to install versions compatible with RN 0.62.2:
@react-native-community/async-storage: Stores search keywords and their corresponding image metadata (like local file paths)react-native-fs: Handles downloading images to your app's private storage
Run these commands to install:
# Using npm npm install @react-native-community/async-storage@1.12.1 react-native-fs@2.16.6 # Or yarn yarn add @react-native-community/async-storage@1.12.1 react-native-fs@2.16.6
RN 0.62 uses auto-linking, so no manual linking is needed for these packages.
2. Core Cache Setup & Logic
We'll split this into initializing storage, handling search with cache-first behavior, and downloading images locally.
2.1 Initialize Cache Directory
First, create a private directory for cached images (so they won't get cleaned up by the system):
import RNFS from 'react-native-fs'; // Define the private cache directory path const CACHE_DIR = `${RNFS.DocumentDirectoryPath}/unsplash_image_cache`; // Create the directory if it doesn't exist const initCacheDirectory = async () => { const directoryExists = await RNFS.exists(CACHE_DIR); if (!directoryExists) { await RNFS.mkdir(CACHE_DIR); } }; // Call this when your app starts (e.g., in a useEffect hook) useEffect(() => { initCacheDirectory(); }, []);
2.2 Cache-First Search Function
This function will first check for cached results, and only hit the Unsplash API if no local data exists. It also downloads images to local storage and saves metadata for future use:
import AsyncStorage from '@react-native-community/async-storage'; const searchUnsplashImages = async (searchQuery) => { // Check local cache first const cachedResultsKey = `unsplash_search_${searchQuery}`; const cachedData = await AsyncStorage.getItem(cachedResultsKey); if (cachedData) { console.log(`Loading cached results for "${searchQuery}"`); return JSON.parse(cachedData); } // If no cache, fetch from Unsplash API try { const unsplashApiUrl = `https://api.unsplash.com/search/photos?query=${searchQuery}&per_page=30&client_id=YOUR_UNSPLASH_ACCESS_KEY`; const response = await fetch(unsplashApiUrl); if (!response.ok) throw new Error('API request failed'); const apiData = await response.json(); const rawImages = apiData.results; // Download each image to local storage and attach local path to metadata const cachedImages = await Promise.all(rawImages.map(async (image) => { const localFilePath = `${CACHE_DIR}/${image.id}.jpg`; const imageExistsLocally = await RNFS.exists(localFilePath); // Only download if the image isn't already cached if (!imageExistsLocally) { await RNFS.downloadFile({ fromUrl: image.urls.regular, toFile: localFilePath, }).promise; } return { ...image, localPath: localFilePath }; })); // Save the cached metadata to AsyncStorage await AsyncStorage.setItem(cachedResultsKey, JSON.stringify(cachedImages)); return cachedImages; } catch (error) { console.error('Search failed:', error); // Throw error to handle offline/no-cache scenarios in UI throw new Error('No cached results found and unable to fetch new data. Check your internet connection.'); } };
Note: Replace YOUR_UNSPLASH_ACCESS_KEY with your actual Unsplash API key.
2.3 FlatList with Local Image Rendering
Update your FlatList to use the local cached image first, falling back to the remote URL if the local file is missing:
<FlatList data={yourImageListState} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <Image source={{ uri: item.localPath ? `file://${item.localPath}` : item.urls.regular }} style={{ width: '100%', height: 220, marginVertical: 8, borderRadius: 8 }} resizeMode="cover" /> )} />
The file:// prefix is required for React Native's Image component to recognize local file paths.
3. Offline & App Restart Behavior
This setup handles both scenarios automatically:
- App Restart: When the app launches again, calling
searchUnsplashImageswill pull metadata from AsyncStorage and load local images immediately. - Offline Mode: If the user searches a query that's already cached, results load without an internet connection. For new queries, the error handler will notify the user they're offline.
4. Optional: Cache Cleanup Function
Add this if you want to let users clear cached data to free up space:
const clearAllCache = async () => { // Delete all cached image files await RNFS.unlink(CACHE_DIR); // Remove all search metadata from AsyncStorage const allStorageKeys = await AsyncStorage.getAllKeys(); const cacheKeys = allStorageKeys.filter(key => key.startsWith('unsplash_search_')); await AsyncStorage.multiRemove(cacheKeys); // Recreate the empty cache directory await initCacheDirectory(); // Reset your image list state setYourImageListState([]); };
Key Notes
- Permissions: iOS doesn't require extra permissions (we're using the app's private document directory). For Android 10+, scoped storage is handled automatically by
react-native-fs. - Cache Size: Add logic to monitor cache size over time if you want to prevent excessive storage usage.
- Unsplash Limits: Caching reduces API calls, which helps you stay within Unsplash's rate limits.
内容的提问来源于stack exchange,提问作者Mrinal Maheshwari

