React-Native中用CameraRoll实现相册图片懒加载的问题求助
React Native CameraRoll 分批加载相册图片方案
针对你使用@react-native-community/cameraroll@^1.8.1实现FlatList分批加载相册图片的需求,以下是可行的实现方案,核心是利用CameraRoll的分页参数结合FlatList的滚动触底事件实现增量加载:
核心思路
- 维护分页关键状态:已加载图片数组、上一页游标(
lastCursor)、是否还有更多数据(hasMore)、加载状态(loading) - 初始加载第一页(前100张)数据
- 监听FlatList滚动到底部事件,触发下一页数据请求
- 每次请求传入上一页游标,获取下一批100张图片,更新状态并合并数据
- 根据返回的分页信息判断是否还有更多数据,终止后续无效请求
完整代码示例
import React, { useState, useEffect } from 'react'; import { View, FlatList, Image, ActivityIndicator } from 'react-native'; import CameraRoll from '@react-native-community/cameraroll'; const AlbumImageList = () => { const [images, setImages] = useState([]); const [lastCursor, setLastCursor] = useState(null); const [hasMore, setHasMore] = useState(true); const [loading, setLoading] = useState(false); const PAGE_SIZE = 100; // 初始加载第一页数据 useEffect(() => { fetchImages(); }, []); // 批量获取相册图片的核心函数 const fetchImages = async () => { if (loading || !hasMore) return; setLoading(true); try { const params = { first: PAGE_SIZE, ...(lastCursor && { after: lastCursor }), // 存在游标时传入分页参数 assetType: 'Photos', // 仅加载图片,可按需调整 }; const result = await CameraRoll.getPhotos(params); const newImages = result.edges.map(item => item.node.image.uri); // 合并新图片到已有数组 setImages(prev => [...prev, ...newImages]); // 更新分页游标 setLastCursor(result.page_info.end_cursor); // 判断是否还有更多数据 setHasMore(result.page_info.has_next_page); } catch (error) { console.error('加载相册图片失败:', error); } finally { setLoading(false); } }; // FlatList触底加载下一页 const handleLoadMore = () => { if (hasMore && !loading) { fetchImages(); } }; // 渲染图片项 const renderItem = ({ item }) => ( <Image source={{ uri: item }} style={{ width: 100, height: 100, margin: 2 }} resizeMode="cover" /> ); // 渲染底部加载指示器 const renderFooter = () => { if (!loading) return null; return ( <View style={{ paddingVertical: 20 }}> <ActivityIndicator size="small" /> </View> ); }; return ( <FlatList data={images} renderItem={renderItem} numColumns={3} onEndReached={handleLoadMore} onEndReachedThreshold={0.1} // 距离底部10%时触发加载 ListFooterComponent={renderFooter} keyExtractor={(item, index) => index.toString()} /> ); }; export default AlbumImageList;
关键注意点
loading状态必须严格控制,避免同一时间发起多个重复请求page_info.has_next_page是判断是否还有更多数据的核心依据,当它为false时要设置hasMore为false,停止后续加载onEndReachedThreshold可根据需求调整,数值越小,触发加载的时机越晚- 需在Android和iOS平台配置对应的相册权限,否则无法正常获取图片
内容的提问来源于stack exchange,提问作者ChrissyBe
相关产品推荐
相关产品推荐

