简体   繁体   English

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

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

The following component CapturePhoto is used to take a photo using react-native Image Picker, once a photo is taken, I copy the photo file to a specific path that I pass as prop to this component from its parent ( a gallery of images that is a list of the CapturePhoto component) The reason I am copying the photo is that I cannot find another way to specify the path to Image picker as option.以下组件 CapturePhoto 用于使用 react-native Image Picker 拍摄照片,拍摄照片后,我将照片文件复制到特定路径,该路径作为 prop 从其父组件传递给该组件(图像库是一个列表CapturePhoto 组件的)我复制照片的原因是我找不到另一种方法来将图像选择器的路径指定为选项。

The code works for taking a photo and copying the file image to the specific path but the photo is not being displayed until I take a second photo (delay)该代码适用于拍照并将文件图像复制到特定路径,但直到我拍第二张照片(延迟)才显示照片

I am learning react-native and Javascript at the same time, I know it's not the good way but I don't have time to learn Javascript first!我正在同时学习react-native和Javascript,我知道这不是好方法但是我没有时间先学习Javascript!

Any guidance provided would be much appreciated!提供的任何指导将不胜感激!

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
  }
});

You don't actually need any states for saving image picker response.您实际上不需要任何状态来保存图像选择器响应。 If you want to save the uri of the image which was clicked you can have a state for it and add the code for it inside copyPhoto() after file has been copied.如果你想保存被点击的图像的 uri,你可以为它设置一个 state 并在复制文件后在copyPhoto()中添加它的代码。

var RNFS = require('react-native-fs'); This statement should not be inside function. Everytime the component re-renders it will require it again.这个语句不应该在 function 里面。每次组件重新渲染它都会再次需要它。 Add it like you've added import statements.添加它就像添加导入语句一样。

You should change your functions like this.你应该像这样改变你的功能。

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);
  }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM