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

如何使用Expo Image Picker向AWS批量上传图片

批量上传图片到AWS Amplify的修复方案

核心问题分析

你的代码无法实现批量上传主要有以下几个问题:

  • 函数组件错误使用this关键字,导致方法调用失败
  • Expo ImagePicker多选返回的结构是assets数组,直接遍历pickerResult无效
  • Blob对象没有name属性,上传时文件名会丢失
  • 状态更新错误,上传后的图片会被覆盖而非追加到列表
  • 部分方法未正确绑定作用域,导致执行报错

修复后的完整代码

import { Amplify, Auth, Storage } from "aws-amplify";
import * as Clipboard from "expo-clipboard";
import * as ImagePicker from "expo-image-picker";
import { useState } from "react";
import { Button, Image, Text, View, StyleSheet } from "react-native";
import awsconfig from "../aws-exports";

Amplify.configure(awsconfig);

const UploadImageAWS = () => {
  const [images, setImages] = useState([]);
  const [uploadProgress, setUploadProgress] = useState({});

  // 选择图片
  const pickImage = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      aspect: [4, 3],
      quality: 1,
      allowsMultipleSelection: true,
    });

    if (!result.canceled) {
      handleImagePicked(result.assets);
    }
  };

  // 处理选中的图片数组
  const handleImagePicked = async (assets) => {
    try {
      // 遍历选中的每个图片
      for (const asset of assets) {
        // 生成唯一文件名,避免覆盖
        const filename = `${Date.now()}-${Math.random().toString(36).substring(2)}.jpg`;
        const imgBlob = await fetchImageFromUri(asset.uri);
        const uploadKey = await uploadImage(filename, imgBlob, filename);
        const downloadUrl = await Storage.get(uploadKey, { level: "public" });
        // 追加图片到列表
        setImages(prev => [...prev, downloadUrl]);
      }
    } catch (e) {
      console.error("上传失败", e);
      alert("上传失败");
    }
  };

  // 上传图片到S3
  const uploadImage = (filename, imgBlob, key) => {
    return Storage.put(key, imgBlob, {
      level: "public",
      contentType: "image/jpeg",
      progressCallback(progress) {
        const percentage = parseInt((progress.loaded / progress.total) * 100);
        // 更新对应文件的上传进度
        setUploadProgress(prev => ({ ...prev, [key]: percentage }));
      },
    })
    .then(response => response.key)
    .catch(error => {
      console.error("上传错误", error);
      throw error;
    });
  };

  // 从URI获取Blob对象
  const fetchImageFromUri = async (uri) => {
    const response = await fetch(uri);
    return response.blob();
  };

  // 复制单个图片URL到剪贴板
  const copyToClipboard = (url) => {
    Clipboard.setString(url);
    alert("图片URL已复制到剪贴板");
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>AWS Storage 批量上传Demo</Text>

      {/* 显示每个图片的上传进度 */}
      {Object.entries(uploadProgress).map(([key, percentage]) => (
        percentage < 100 && (
          <Text key={key} style={styles.percentage}>
            上传中: {percentage}%
          </Text>
        )
      ))}

      {/* 显示已上传的图片列表 */}
      {images.map((imgUrl, index) => (
        <View key={index} style={styles.imageContainer}>
          <Text onPress={() => copyToClipboard(imgUrl)} style={styles.result}>
            <Image source={{ uri: imgUrl }} style={styles.image} />
          </Text>
          <Text style={styles.info}>点击图片复制URL</Text>
        </View>
      ))}

      <Button onPress={pickImage} title="从相册选择图片" />
    </View>
  );
};

// 样式定义
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    paddingTop: 50,
    paddingHorizontal: 20,
  },
  title: {
    fontSize: 20,
    fontWeight: "bold",
    marginBottom: 20,
  },
  percentage: {
    fontSize: 16,
    marginVertical: 10,
  },
  imageContainer: {
    marginVertical: 15,
    alignItems: "center",
  },
  image: {
    width: 250,
    height: 250,
    borderRadius: 8,
  },
  result: {
    marginVertical: 10,
  },
  info: {
    fontSize: 12,
    color: "#666",
  },
});

export default UploadImageAWS;

关键修复点说明

  • 移除this关键字,函数组件内直接定义并调用方法
  • 正确处理ImagePicker返回的assets数组,遍历选中的图片
  • 生成唯一文件名,避免S3上的文件覆盖
  • 使用函数式更新状态setImages(prev => [...prev, downloadUrl]),确保图片追加而非替换
  • 为每个上传文件单独维护进度,避免批量上传时进度混乱
  • 调整复制功能,支持复制单个图片的URL
  • 完善错误捕获与日志输出,便于排查问题

内容的提问来源于stack exchange,提问作者Laspeed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:10:37