如何使用 Expo Image Picker 在 React Native 中将图像 uri 从一个屏幕传递到另一个屏幕?

How to pass Image uri from one screen to other, in React Native, using Expo Image Picker?

我想将图像 uri 传递到下一个屏幕,这样我就可以 select 在一个屏幕上显示图像并在另一个屏幕上显示,有什么可行的方法吗?我正在从 Info.js 中选择图像,并希望在 Profile.js 中显示 selected 图像。 我正在使用 React Native 版本 0.64.3,并在 Linux 中建立在 Expo 之上。 Expo Image Picker 版本为 12.0.1 我的代码如下;

Info.js

export default function Info({ route, navigation }) {
    const [modalVisible, setModalVisible] = useState(false);
    const [profilePicture, setprofilePicture] = useState('');

    const pickImage = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
            mediaTypes: ImagePicker.MediaTypeOptions.Images,
            allowsEditing: true,
            aspect: [1, 1],
            quality: 1,
        });

        if (!result.cancelled) {
            setprofilePicture(result.uri);
            setModalVisible(false);
        }
    }
    const openCamera = async () => {
        const permissionResult = await ImagePicker.requestCameraPermissionsAsync({
            mediaTypes: ImagePicker.MediaTypeOptions.Images,
            allowsEditing: true,
            aspect: [1, 1],
            quality: 1,
        });
        if (permissionResult.granted === false) {
            alert("You've refused to allow this appp to access your camera!");
            return;
        }
        const result = await ImagePicker.launchCameraAsync();
        // console.log(result);
        if (!result.cancelled) {
            setprofilePicture(result.uri);
            setModalVisible(false);
        }
    }
    
    if (profilePicture != '') {
        nextbtn = <NextBtn txt={"Next"} onPress={() => { navigation.navigate('Profile', { profile: profilePicture }) }} />
    } else {
        nextbtn = <Text></Text>
    }
    var bg = ''
    if (profilePicture != '') {
        bg = { backgroundColor: 'transparent' }
    }

    return (
        <View style={{ flex: 1 }}>
            <View style={[s.surface, s.fullView, {paddingTop: 64}]}>
                {nextbtn}
                <Text style={[s.heading2, s.onSurface, s.container]}>Your Info</Text>
                <Text style={[s.txt, s.onSurface, s.containerLg, s.mt1, s.lhNormal, s.textCenter]}>Enter your name and add a profile picture.</Text>
                <ImageBackground
                    source={{ uri: profilePicture }}
                    resizeMode="cover"
                    style={{ marginTop: 18 }}
                    imageStyle={{ borderRadius: 100 }}
                >
                    <TouchableOpacity
                        style={[s.profileSelector, bg]}
                        onPress={() => { setModalVisible(true) }}
                    >
                        <FontAwesomeIcon icon={faCamera} size={20} color={color.onSurfaceColor} />
                    </TouchableOpacity>
                </ImageBackground>
            </View>
            <Modal
                animationType="fade"
                transparent={true}
                visible={modalVisible}
                statusBarTranslucent={true}
                onRequestClose={() => {
                    Alert.alert('Modal has been closed.');
                    setModalVisible(!modalVisible);
                }}
            >
                <View style={[s.centeredView, s.bgOverlay]}>
                    <View style={s.modalView}>
                        <Text style={s.modalText}>Choose Info Picture</Text>
                        <View style={[s.dFlex, {flexDirection: 'row'}]}>
                            <TouchableOpacity
                                style={[s.profieSelection]}
                                onPress={openCamera}
                            >
                                <FontAwesomeIcon icon={faCamera} size={20} color={color.onSecondaryColor} />
                            </TouchableOpacity>
                            <TouchableOpacity
                                style={[s.profieSelection]}
                                onPress={pickImage}
                            >
                                <FontAwesomeIcon icon={faImages} size={20} color={color.onSecondaryColor} />
                            </TouchableOpacity>
                        </View>
                        <Pressable
                            style={[s.btn, { minWidth: 260 }]}
                            onPress={() => setModalVisible(!modalVisible)}
                        >
                            <Text style={[s.btnText]}>Cancel</Text>
                        </Pressable>
                    </View>
                </View>
            </Modal>
        </View >
    )

}

Profile.js


export default function Profile({ route, navigation }) {
    const { profile } = route.params;
    var profilePicture = JSON.stringify(profile);
    console.log(profilePicture)
eturn (
        <View style={{ flex: 1 }}>
            <View style={[s.surface, s.fullView, { paddingTop: 64 }]}>
                <Text style={[s.heading2, s.onSurface, s.container]}>Your Profile</Text>
                <Text style={[s.txt, s.onSurface, s.containerLg, s.mt1, s.mb2, s.lhNormal, s.textCenter]}>Enter your name and add a profile picture.</Text>
                <Image source={profilePicture} style={{ width: 136, borderRadius: 100, height: 136, backgroundColor: '#fff' }} />
            </View>
        </View >
    )

}

你好像用的是 React Navigation,heres 官方指南如何使用 React Navigation 传递参数给路由

您可以从一个屏幕获取图像的 uri 并通过导航参数将其传递到另一个屏幕。 查看 @react-navigation/native

const navigation = useNavigation();

const onPickImage = () => {
   // expo image picker codes here 

   navigation.navigate('SecondScreen', { uri });
}

我想通了,我实际上是在使用 Json.Stringify,它在字符串中包含“”(引号),这是导致问题的原因,您可以删除“,也可以完全跳过字符串化。 即

export default function Profile({ route, navigation }) {
    const { profile } = route.params;
eturn (
        <View style={{ flex: 1 }}>
            <View style={[s.surface, s.fullView, { paddingTop: 64 }]}>
                <Text style={[s.heading2, s.onSurface, s.container]}>Your Profile</Text>
                <Text style={[s.txt, s.onSurface, s.containerLg, s.mt1, s.mb2, s.lhNormal, s.textCenter]}>Enter your name and add a profile picture.</Text>
                <Image source={profile} style={{ width: 136, borderRadius: 100, height: 136, backgroundColor: '#fff' }} />
            </View>
        </View >
    )

}