使用图像选择器处理异步任务和在 react-native 中复制文件的困难

Difficulties handling asynchronous taks using image-picker and copying files in react-native

以下组件 CapturePhoto 用于使用 react-native Image Picker 拍摄照片,拍摄照片后,我将照片文件复制到特定路径,作为 prop 从其父组件传递给此组件( a图片库是 CapturePhoto 组件的列表)我复制照片的原因是我找不到另一种方法来将图像选择器的路径指定为选项。

该代码适用于拍摄照片并将文件图像复制到特定路径,但直到我拍摄第二张照片(延迟)才显示照片

我正在同时学习react-native和Javascript,我知道这不是好方法,但我没有时间先学习Javascript!

如能提供任何指导,我们将不胜感激!

import React, { useState } from 'react';
import { TouchableOpacity, View, Image, StyleSheet, Text } from 'react-native';
import * as ImagePicker from 'react-native-image-picker';
import placeHolder from "./placeHolder.png"

export default function CapturePhoto({ photoPath }) {

  let uri;
  let decodedURI;
  const [pickerResponse, setPickerResponse] = useState(null);
  
  var RNFS = require('react-native-fs');


  const copyPhoto = (source, destination) => {
    if (source === undefined || destination === undefined) {
      return;
    } else {
      RNFS.copyFile(source, destination)
        .then((result) => {
          console.log("\n\n>>>>>>>>>>>>The photo has been copied ")

        }).catch((error) => {
          console.log("\n\n>>>>>>>>>>>>Copy photo failed: ", error)
        })
    }
  }

  const onCameraPress = async () => {
    const options = {
      saveToPhotos: true,
      mediaType: 'photo',
      includeBase64: false,
    };
    ImagePicker.launchCamera(options, setPickerResponse);
    uri = pickerResponse?.assets && pickerResponse.assets[0].uri;
    console.log("\n\n>>>>>>>>>>>>destination photo: ", photoPath);
    decodedURI = decodeURIComponent(uri)
    await uri ? copyPhoto(decodedURI, photoPath) : console.log("\n\n>>>>>>>>>>>>The photo has not been copied ")
  }


  return (
    <View style={{
      justifyContent: 'center',
      alignItems: 'center',
      marginTop: 10
    }}>
      <TouchableOpacity onPress={() => onCameraPress()}>
        
        <Image
          style={styles.avatarImage}
          source={uri ? { uri } : placeHolder}
        />
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  avatarImage: {
    height: 260,
    width: 260,
    overflow: 'hidden',
    margin: 10
  }
});

您实际上不需要任何状态来保存图像选择器响应。如果你想保存被点击的图像的 uri,你可以为它设置一个状态,并在复制文件后在 copyPhoto() 中添加它的代码。

var RNFS = require('react-native-fs'); 这个语句不应该在函数内部。每次组件 re-renders 它都会再次需要它。像添加导入语句一样添加它。

你应该像这样改变你的功能。

const copyPhoto = (source, destination) => {
  if (source === undefined || destination === undefined) {
    return;
  } else {
    RNFS.copyFile(source, destination)
      .then((result) => {
        console.log("\n\n>>>>>>>>>>>>The photo has been copied ");
      })
      .catch((error) => {
        console.log("\n\n>>>>>>>>>>>>Copy photo failed: ", error);
      });
  }
};

const onCameraPress = async () => {
  const options = {
    saveToPhotos: true,
    mediaType: "photo",
    includeBase64: false
  };
  const result = await ImagePicker.launchCamera(options);

  //if the user cancelled the process
  if (result.didCancel) {
    return alert("You cancelled the process");
  }

  const {assets} = result;

  if (assets.length > 0) {
    const decodedUri = decodeURIComponent(assets[0].uri);
    copyPhoto(decodedUri, photoPath);
  }
};