You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Native中用CameraRoll实现相册图片懒加载的问题求助

React Native CameraRoll 分批加载相册图片方案

针对你使用@react-native-community/cameraroll@^1.8.1实现FlatList分批加载相册图片的需求,以下是可行的实现方案,核心是利用CameraRoll的分页参数结合FlatList的滚动触底事件实现增量加载:

核心思路

  1. 维护分页关键状态:已加载图片数组、上一页游标(lastCursor)、是否还有更多数据(hasMore)、加载状态(loading)
  2. 初始加载第一页(前100张)数据
  3. 监听FlatList滚动到底部事件,触发下一页数据请求
  4. 每次请求传入上一页游标,获取下一批100张图片,更新状态并合并数据
  5. 根据返回的分页信息判断是否还有更多数据,终止后续无效请求

完整代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:50:46