0

在 React-Native 中,我正在创建一个名为 ImageSelector 的功能组件,其中我使用 expo-image-picker 并将图像 URI 用作使用 Formik 的父组件中的必填字段。我的模拟器工作正常,我能够成功选择通用图像并在控制台中记录图像 URI('success:' + result.uri),但出现以下错误:

我想在下面的图像组件中显示图像,但图像不显示(它不会中断)。我收到以下错误Unhandled Promise Rejection: ReferenceError: Can't find variable: props我想这是指父表单组件,但我不知道要改变什么才能让这个错误消失。

父组件

import { View, Text, Button } from 'react-native';
import { Formik } from 'formik';
import * as yup from 'yup';
import ImageSelector from '../shared/imagePicker';

const newPostSchema = yup.object({
    image: yup.string()
        .required(),
})

export default function CreatePost({navigation}) {

    const setImageURI = (image) => {
        props.setFieldValue('imageUri', image.uri)
    }

    return (
        <View style={styles?.container}>
            <Formik
                initialValues={{
                    imageURI: null,
                }}
                validationSchema={newPostSchema}
                onSubmit={(values, actions) => {
                    console.log(values);
                    navigation.navigate('ReviewPost', {
                        imageURI: values.imageURI,
                    });
                }}
            >
            {props => (
                <View>
                    <ImageSelector
                        image={props.values.imageURI}
                        onImagePicked={setImageURI}
                    />
                    <Button onPress={props.handleSubmit} title='REVIEW' />

                </View>
            )}
            </Formik>
        </View>
    )
}

*** Nested ImageSelector Component in another file ***

import React, {useState, useEffect} from 'react';
import {View, Button, Image, StyleSheet} from 'react-native';
import * as ImagePicker from 'expo-image-picker';

const ImageSelector = ({image, onImagePicked}) => {

    const [selectedImage, setSelectedImage] = useState();

    useEffect(() => {
        if(image) {
            console.log('useEffect: ' + image);
            setSelectedImage({uri: image});
        }
    }, [image])

    pickImageHandler = async  () => {
        let result = await ImagePicker.launchImageLibraryAsync({
            title: 'Choose Image',
            maxWidth: 800,
            maxHeight: 600,
            mediaTypes: ImagePicker.MediaTypeOptions.All,
            allowsEditing: true,
            aspect: [4, 3],
            quality: 1
        });
        if (!result.cancelled) {
            console.log('success: ' + result.uri);
            onImagePicked({uri: result.uri});
            console.log('a');
            setSelectedImage({uri: result.uri});
            console.log('b');
        }
        if (result.cancelled) {
            console.log('result cancelled: ' + result.cancelled);
        }

    }

    return (
        <View style={styles.container}>
            <View style={styles.imageContainer}>
                <Image source={selectedImage} />
            </View>
            <View style={styles.button}>
                <Button title='Pick Image' onPress={this.pickImageHandler} />
            </View>
        </View>
    )
}

以下 4 行不执行(控制台日志用于测试以确保它们不会被调用):

  • onImagePicked({uri: result.uri});*
  • 控制台.log('a'); *
  • setSelectedImage({uri: result.uri});*
  • 控制台.log('b');*

我需要消除与道具相关的错误,将 selectedImage 设置为等于 result.uri,并<Image />使用 selectedImage.uri 作为图像源在组件中显示图像。

帮助?

4

1 回答 1

1

这里的问题出在错误消息中。由于您正在创建一个名为 CreatePost 的功能组件,因此传递道具的典型语法是

export default function CreatePost(props) {
...
}

因此,您的组件可以访问传递给它的 props,例如 setFieldValue,但是,您使用了扩展运算符 {navigation} 而不是 props,因此您在执行此操作时已经提取了所有 props。因此,范围不知道任何 props 变量。所以,就目前而言,我会尝试将参数更改为此

export default function CreatePost(props) {
const { navigation } = props;
...
}

这样,在您引用道具的范围内的任何其他地方仍然可以工作,并且您也不会失去对导航属性的访问权限,或者,您也可以简单地将 'navigation.navigate' 更改为 'props.navigation.navigate'。所以javascript说找不到变量props,因为对它来说,这只是一个简单的香草javascript函数,它不直观地知道一个名为props的变量,你必须显式地调用它。

另外,我觉得这部分代码可能仍然存在问题

{props => (
                <View>
                    <ImageSelector
                        image={props.values.imageURI}
                        onImagePicked={setImageURI}
                    />
                    <Button onPress={props.handleSubmit} title='REVIEW' />

                </View>
            )}

因此,如果您可以在使用组件的位置发布代码,以查看您正在传递的道具,例如 setFieldValue、导航等,这将有所帮助。您可以将该部分重写为

<Formik
   initialValues={{
      imageURI: null,
   }}
   validationSchema={newPostSchema}
   onSubmit={(values, actions) => {
      console.log(values);
      navigation.navigate('ReviewPost', {
        imageURI: values.imageURI,
      });
   }}
>
<View>
   <ImageSelector
     image={props.values.imageURI}
     onImagePicked={setImageURI}
   />
  <Button onPress={props.handleSubmit} title='REVIEW' />
</View>

现在无需{props =>像重构那样做部分,您已经可以访问范围内的道具。

于 2020-05-15T20:03:45.643 回答