So I have a an image selector that when I press, it launches the phone image library and then when I select the image it is supposed to fill that image selector but every time i select an image, I get this error
[TypeError: undefined is not an object (evaluating 'iter[Symbol.iterator]')]
This is how my code looks like this is the App file
import React, {useState} from 'react'
import { Button, StyleSheet, Text, View } from 'react-native'
import Screen from './app/components/Screen'
import ImageInputList from './app/components/ImageInputList'
export default function App() {
const [imageUris, setImageUris] = useState();
const handleAdd = (uri) => {
setImageUris([...imageUris, uri])
}
const handleRemove = uri => {
setImageUris(imageUris.filter(imageUri => imageUri !== uri))
}
return (
<Screen>
<ImageInputList imageUris={imageUris} onAddImage={handleAdd} onRemoveImage={handleRemove} />
</Screen>
)
}
And then this is my 2nd component the "imageInputList"
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import ImageInput from './ImageInput'
export default function ImageInputList({imageUris = [], onRemoveImage, onAddImage}) {
return (
<View style={styles.container}>
{imageUris.map((uri) => (
<View key={uri} style={{marginRight: 10}}>
<ImageInput
imageUri={uri}
onChangeImage={() => onRemoveImage(uri)}
/>
</View>
))}
<ImageInput onChangeImage={(uri) => onAddImage(uri)} />
</View>
)
}
And lastly, this is the imageInput component
import React, {useEffect} from 'react'
import { Image, StyleSheet, TouchableWithoutFeedback, Alert, View } from 'react-native'
import {MaterialCommunityIcons} from "@expo/vector-icons"
import * as ImagePicker from "expo-image-picker"
export default function ImageInput({imageUri, onChangeImage}) {
useEffect(() => {
requestPermission();
}, [])
const requestPermission = async () => {
const {granted} = await ImagePicker.requestMediaLibraryPermissionsAsync();
if(!granted) alert("Allow this app to access your image library")
}
const handlePress = () => {
if(!imageUri) selectImage();
else Alert.alert("Delete",
"Are you sure you want to delete this image?",
[{text: "Yes", onPress: onChangeImage(null)}, {text: "No"},])
};
const selectImage = async () => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
quality: 0.5,
});
if(!result.cancelled) onChangeImage(result.uri);
}
catch (error) {
console.log("Something went wrong in your code", error)
}
}
return (
<TouchableWithoutFeedback onPress={handlePress}>
<View style={styles.container} >
{!imageUri && <MaterialCommunityIcons name="camera" size={40} color="grey" />}
{imageUri && <Image source={{uri: imageUri}} style={styles.image} />}
</View>
</TouchableWithoutFeedback>
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#f1f1f1",
borderRadius: 15,
marginTop: 40,
alignItems: 'center',
justifyContent: 'center',
overflow: "hidden",
width: 100,
height: 100,
},
image: {
height: "100%",
width: "100%",
}
})
I know the issue has something to do with "handleAdd" or the "onChangeImage" part but I do not know exactly how to fix them. Thanks in Advance.
CodePudding user response:
The problem is here:
const [imageUris, setImageUris] = useState();
You're trying to spread imageUris but it is not an array when it is first initialized.
Simply replace useState();
with useState([]);