【问题标题】:React Native why does the app crash when sending photo to APIReact Native为什么将照片发送到API时应用程序崩溃
【发布时间】:2022-08-19 16:10:00
【问题描述】:

当用户尝试将照片从相机发送到 API 时,我的应用程序不断崩溃。 android模拟器没有问题,但它在我的物理设备(Galaxy A30)上崩溃。当我在模拟器上使用它时,console.log 没有显示任何内容。从图库提交没有问题,但是从相机提交时,它崩溃了。

import React, {useState, useContext} from \'react\';
import {ScrollView, View, Text, TextInput, TouchableOpacity, Alert} from \'react-native\';
import { AuthContext } from \'../Context/AuthContext\';
import { URLs } from \'../constants/links\';
import * as ImagePicker from \'expo-image-picker\';
import axios from \'axios\';
import * as Permissions from \"expo-permissions\";
import { CAMERA } from \"expo-permissions\";

const MyScreen = ({navigation}) => {
    const { myToken } = useContext(AuthContext)
    const [allImage, setAllImage] = React.useState([]);
    const [pickedImage, setPickedImage] = useState(\"\");
    const [fileName, setFileName] = React.useState(\"\"); 
    const formdata = new FormData();
    
    const cameraPermission = async () => {
      const result = await Permissions.askAsync(CAMERA);
      if (result.status != \"granted\") {
        Alert.alert(
          \"Insufficient Permission\",
          \"You need to grant camera permission to use this app\",
          [{ text: \"Okay\" }]
        );
        return true;
      }
      return true;
    };
    
    const useCamera = async () => {
        const hasPermissions = await cameraPermission();
        if (!hasPermissions) {
            return;
        }
        if(allImage.length < 4){
            let result = await ImagePicker.launchCameraAsync({
                allowsEditing: true,
                quality: 0.5,
            });

            if (!result.cancelled) { 
                const name = result.uri.split(\'/\').pop();
                let match = /\\.(\\w+)$/.exec(name);
                let type = match ? `image/${match[1]}` : `image`;
                let newFile = {
                    uri: result.uri,
                    type: type,
                    name: name
                }
                setAllImage(newFile)
                setPickedImage(result.uri)
                if (!pickedImage && allImage.length === 0) {
                    setAllImage([newFile]); 
                    setFileName(\"Photo 1\")
                }else {
                    setAllImage([...allImage, newFile]); 
                    setFileName(fileName + \", Photo \" + (allImage.length + 1))  
                }
            }
        } else  { 
            Alert.alert(\"Image\", \"You have reach the image upload limit\");
        }
    };

    const fetchData = () => {
        const abortCont = new AbortController(); 
        allImage.forEach((file) => {
            formdata.append(\'files[]\', file);
        });
        axios({
            method: \'post\',
            url: URLs,
            headers: {
                Accept: \"application/json\",
                Authorization: myToken,
                \'Content-Type\': \"multipart/form-data\", 
            },
            data: formdata,
            signal: abortCont.signal,
        }).then(function (result) { 
            if(result.data.message === \"Successfully added\") {
                Alert.alert(\"Upload Successufull\", result.data.message);
                navigation.goBack()
            }

        }).catch(function (error) { 
            Alert.alert(\"Error\", error); 
            formdata = new FormData();
        });
        
        return () => abortCont.abort();
    }
 

    return (
        <ScrollView>
            <View>
                <View>
                    <Text>Attach Receipt File</Text>
                    <View>
                        <TextInput 
                            editable={false}
                            placeholder=\"Select files..\"
                            value={fileName}
                        />
                    </View>
                    <View>
                        <TouchableOpacity activeOpacity={0.8} onPress={useCamera}>
                            <Text>Camera</Text>
                        </TouchableOpacity>
                    </View>

                    <View>
                        <TouchableOpacity activeOpacity={0.9} onPress={fetchData}>
                            <Text>Submit</Text>
                        </TouchableOpacity>
                    </View>
                </View>
            </View>
        </ScrollView>
    );
}

export default MyScreen;
  • 你永远不会定义formData
  • @Phil 那不是问题。在我设置权限之前它工作正常
  • 抱歉,没有。这不是 JavaScript 的工作方式。这将引发类似的错误\"Uncaught ReferenceError: formData is not defined\"
  • @Phil 它已经定义了。我没有把整个代码放在这里,因为代码太长,无法在这里提交。
  • 请参阅How to create a Minimal, Reproducible Example。其他人应该能够获取您的代码,自己运行它并遇到您看到的相同问题,而不是由于缺少部分而导致的其他问题

标签: javascript react-native


【解决方案1】:

我仍然不知道当用户发送从相机拍摄的照片时应用程序崩溃的原因,但我找到了解决方案。我从使用 expo-permission 的相机更改为从 expo-camera 使用相机。这是文档:https://docs.expo.dev/versions/latest/sdk/camera/#cameracapturedpicture

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 2020-03-16
    相关资源
    最近更新 更多