Flat List Data is not showing - javascript

I am using flatlist for show user input notes in my app. But Flat List is not render any item that i entered. I used static list for testing and it works correctly. but when i enter a text through textinput it is not showing.
const addToDoHandler = () => {
if(userInput == ''){
return;
}
const newTodo = {
id: Math.floor(Math.random() * 1000),
text: userInput,
completed: false,
};
const newTodos = [...todos, newTodo];
setTodos(newTodos);
//clear user input
setUserInput('');
};
const renderItem = ( {item} ) => {
<View style={{backgroundColor:'#6b4d87', marginVertical: 10, flexDirection:'row', alignItems:'center', justifyContent:'space-between', height:60, width:'95%', borderRadius:10 }}>
<View>
<Text style={{color:'black', fontSize:20, fontWeight:'bold'}}>{item.text}</Text>
</View>
<TouchableOpacity onPress={() => deleteHandler(item.id)}>
<TrashIcon size={35} name="trash" style={{color:'#eff9f0'}} />
</TouchableOpacity>
</View>
};
return (
<SafeAreaView style={styles.root}>
<View style={styles.txtInputView}>
<TextInput
value={userInput}
onChangeText={text => setUserInput(text)}
style={styles.textInput}
placeholder={"Enter Your Note..."}
/>
<TouchableOpacity style={styles.addButton} onPress={addToDoHandler}>
<PlusSign size={35} name="add-sharp" style={styles.plusIcon}/>
</TouchableOpacity>
</View>
<View style={{alignItems:'center'}}>
<FlatList
data={todos}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
</SafeAreaView>
);

You need to return the components from renderItem.
Change it to:
const renderItem = ( {item} ) => (
<View style={{backgroundColor:'#6b4d87', marginVertical: 10, flexDirection:'row', alignItems:'center', justifyContent:'space-between', height:60, width:'95%', borderRadius:10 }}>
<View>
<Text style={{color:'black', fontSize:20, fontWeight:'bold'}}>{item.text}</Text>
</View>
<TouchableOpacity onPress={() => deleteHandler(item.id)}>
<TrashIcon size={35} name="trash" style={{color:'#eff9f0'}} />
</TouchableOpacity>
</View>
);

Related

Deleting wrong image from array

I'm trying to delete selected image from an array of images and yet only the first image on the list gets deleted whenever i tap any other image to delete. This is surprising cause i implemented the same method when generating a list in the same screen and it deletes the correct list item each time i tap on it to delete.
Here is all the code in the file excluding cascading styles. Its a lot but i Hope this helps.
const AddPost = () => {
const navigation = useNavigation();
// Thumbnail State
const [thumbnail, setThumbnail] = useState(null);
// Media State
const [media, setMedia] = useState([]);
// Details State
const [title, setTitle] = useState('');
const [category, setCategory] = useState('');
const [caption, setCaption] = useState('');
const [price, setPrice] = useState('');
const [details, setDetails] = useState(false);
// Store State
const [itemName, setItemName] = useState('');
const [itemPrice, setItemPrice] = useState('');
const [photoArray, setPhotoArray] = useState([]);
const [storeItems, setStoreItems] = useState([]);
const width = useWindowDimensions().width;
const numColumns = Math.ceil(width / 120);
const pickThumbnail = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.5,
});
if (!result.cancelled) {
setThumbnail(result.uri);
}
};
const pickMedia = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.2,
});
if (!result.cancelled) {
setMedia([...media, result.uri]);
}
};
const deleteMedia = (index) => {
let removeMedia = [...media];
removeMedia.splice(index, 1);
setMedia(removeMedia)
console.log(index)
};
const addDetailItem = () => {
if (title == '' || category == '' || caption == '' || price == '') {
Alert.alert('Error', 'Please fill in the item detail.')
} else {
Keyboard.dismiss();
setDetails(true);
detailsRef?.current?.close();
};
};
const detailsRef = useRef(null);
const toggleModal = () => {
detailsRef?.current?.present();
}
const toggleModalClose = () => {
detailsRef?.current?.close();
}
const addItem = {
id: Math.floor(Math.random() * 11),
itemName: itemName,
itemPrice: itemPrice,
photo: photoArray
};
const storeRef = useRef(null);
const toggleStoreModal = () => {
storeRef?.current?.present();
}
const toggleStoreModalClose = () => {
storeRef?.current?.close();
}
const addStoreItem = () => {
if (itemName == '' || itemPrice == '') {
Alert.alert('Error', 'Please fill in the item detail.')
} else {
Keyboard.dismiss();
setStoreItems([...storeItems, addItem]);
setItemName(null);
setItemPrice(null);
setPhotoArray([]);
};
};
const deleteItem = (index) => {
let removeItem = [...storeItems];
removeItem.splice(index, 1);
setStoreItems(removeItem)
};
const pickPhoto = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.2,
});
if (!result.cancelled) {
setPhotoArray([...photoArray, result.uri]);
}
};
const deletePhoto = (index) => {
let removeItem = [...photoArray];
removeItem.splice(index, 1);
setPhotoArray(removeItem)
};
const store = () => {
setStoreItems([...storeItems]);
storeRef?.current?.close();
Keyboard.dismiss();
};
return (
<View style={styles.container}>
{/* Header */}
<Header
title={'Add Post'}
leftComponent={
<View style={styles.headerLeft}>
<Image source={images.logo} style={{ height: 28, width: 28, tintColor: COLORS.primary2}} />
</View>
}
rightComponent={
<TouchableOpacity
style={{
width: 50,
height: 50,
alignItems: 'center',
justifyContent: 'center',
}}
onPress= {() => console.log('Post Sumbitted') }
>
<Image
source={icons.post2}
style={{
width: 35,
height: 35,
tintColor: COLORS.primary2,
}}
/>
</TouchableOpacity>
}
/>
<View style={styles.subContainer}>
<ScrollView>
<Text style={styles.textDetail}>Add a photo or video post with thumbnail, category, caption, price, and store details (Optional).</Text>
{/* Add Thumbnail */}
<AddPostItem label={'Thumbnail'} onPress={pickThumbnail}/>
{thumbnail &&
<View style={styles.thumbnail}>
<Image source={{ uri: thumbnail }} style={styles.thumbnailPhoto} />
</View>
}
{/* Add Media */}
<AddPostItem label={'Media (Video/Photo)'} onPress={pickMedia} />
<View style={{flexDirection: 'row'}}>
{Array.from(Array(numColumns)).map((col, colIndex) => (
<View style={{flex: 1}} key={colIndex}>
{media
.filter((item, index) => index % numColumns === colIndex)
.map((item, index) => (
<View key={index.toString()} style={styles.mediaContainer} >
<Image source={{uri: item}} style={styles.addedMedia}/>
<TouchableOpacity style={styles.imageCancel} key={index} onPress={() => deleteMedia(index)}>
<Image source={icons.cross} style={styles.imageCancelIcon}/>
</TouchableOpacity>
</View>
))}
</View>
))
}
</View>
{/* Add Details */}
<AddPostItem label={'Details (Title, Caption, etc)'} onPress={toggleModal}/>
{details &&
<View style={{marginHorizontal: 20}}>
<View style={{flexDirection: 'row', }}>
<Text style={{color: COLORS.primary2, ...FONTS.body4}}>Title: </Text>
<Text style={{color: COLORS.white, ...FONTS.body4}}>{title}</Text>
</View>
<View style={{flexDirection: 'row', marginTop: 5,}}>
<Text style={{color: COLORS.primary2, ...FONTS.body4}}>Category: </Text>
<Text style={{color: COLORS.white, ...FONTS.body4}}>{category}</Text>
</View>
<View style={{flexDirection: 'row', marginTop: 5,}}>
<Text style={{color: COLORS.primary2, ...FONTS.body4}}>Price: </Text>
<Text style={{color: COLORS.white, ...FONTS.body4}}>N{price}</Text>
</View>
<View style={{marginTop: 5,}}>
<Text style={{color: COLORS.primary2, ...FONTS.body4}}>Caption: </Text>
<Text style={{color: COLORS.white, ...FONTS.body4}}>{caption}</Text>
</View>
</View>
}
{/* Add Store */}
<AddPostItem label={'Store Items (Optional)'} onPress={toggleStoreModal}/>
{storeItems.map((item, index) => {
return (
<View key={index.toString()} style={styles.itemContainer}>
<Text style={styles.itemName}>{item?.itemName}</Text>
<Text style={styles.itemPrice}>N{item?.itemPrice}</Text>
</View>
)
})
}
<View>
</View>
</ScrollView>
</View>
<BottomSheetModal
enablePanDownToClose={true}
ref={detailsRef}
snapPoints={['100%']}
index={0}
backgroundComponent={
({style}) =>
<View style={[style, {
backgroundColor: COLORS.primary,
borderRadius: 30,
}]}/>}
>
{/* Post Details */}
{/* Header */}
<ModalHeader left={toggleModalClose} right={addDetailItem} />
<View style={{flex: 1, backgroundColor: COLORS.primary3, borderTopRightRadius: 35, borderTopLeftRadius: 35}}>
<View style={styles.addDetailText}>
<Text style={styles.textHeader}>Add details</Text>
<Text style={styles.textBody}>Provide the necessary details for your post.</Text>
</View>
<View style={{paddingHorizontal: 10}}>
<FormInput
autoCapitalize='words'
placeholder={'Give it a title'}
onChange={setTitle}
value={title}
/>
<FormInput
autoCapitalize='words'
placeholder={'Category'}
onChange={setCategory}
value={category}
/>
<FormMultiText
autoCapitalize='sentences'
placeholder={'Caption'}
onChange={setCaption}
multiline={true}
numberOfLines={4}
value={caption}
/>
<FormInput
keyboardType='number-pad'
placeholder={'Price (Optional)'}
onChange={setPrice}
value={price}
/>
</View>
<Text style={{color: COLORS.gray, ...FONTS.body5, paddingHorizontal: 10, marginTop: 5, marginLeft: 65}}>Leave this input empty for a "FREE POST".</Text>
</View>
</BottomSheetModal>
<BottomSheetModal
enablePanDownToClose={false}
ref={storeRef}
snapPoints={['100%']}
index={0}
backgroundComponent={
({style}) =>
<View style={[style, {
backgroundColor: COLORS.primary,
borderRadius: 30,
}]}/>}
>
<ModalHeader left={toggleStoreModalClose} right={store} />
<View style={styles.storeItemConatainer}>
<View style={{flex: 1, backgroundColor: COLORS.primary3, borderTopRightRadius: 35, borderTopLeftRadius: 35}}>
<View >
<View style={styles.titleBar}>
<Text style={styles.textHeader}>Add store items (Optional)</Text>
</View>
<Text style={styles.textBody}>Include items available for purchase and their item price. You can add more than one item and multiple photo(s) to each item.</Text>
</View>
{/* Store Items */}
<TouchableOpacity onPress={pickPhoto} style={styles.addPhotoBtn}>
<Text style={{color: COLORS.primary, textAlign: 'center', ...FONTS.body3}}>Add Photo(s)</Text>
</TouchableOpacity>
{/* Photo Container */}
<View style={{flexDirection: 'row'}}>
{Array.from(Array(numColumns)).map((col, colIndex) => (
<View style={{flex: 1}} key={colIndex}>
{photoArray
.filter((item, index) => index % numColumns === colIndex)
.map((item, index) => (
<View key={index.toString()} style={styles.photoContainer}>
<Image source={{uri: item}} style={styles.addedPhoto}/>
<TouchableOpacity style={styles.photoCancel} onPress={() => deletePhoto(index)}>
<Image source={icons.cross} style={styles.photoCancelIcon}/>
</TouchableOpacity>
</View>
))}
</View>
))
}
</View>
<View style={styles.storeInput}>
<TouchableOpacity onPress={addStoreItem}>
<View style={styles.iconContainer}>
<Image source={icons.add} style={styles.icon}/>
</View>
</TouchableOpacity>
<View >
<FormStoreInput
autoCapitalize='words'
placeholder={'Item Name'}
onChange={setItemName}
value={itemName}
/>
<FormStoreInput
keyboardType='number-pad'
placeholder={'Item Price'}
onChange={setItemPrice}
value={itemPrice}
/>
</View>
</View>
<BottomSheetScrollView>
{storeItems.map((item, index) => {
return (
<View key={index.toString()} style={{flexDirection: 'row', marginBottom: 10, marginTop: 5}}>
<AddStoreItem items={item}/>
<TouchableOpacity style={styles.cancel} key={index} onPress={() => deleteItem(index)}>
<Image source={icons.cross} style={styles.cancelIcon}/>
</TouchableOpacity>
</View>
)
})
}
</BottomSheetScrollView>
</View>
</View>
</BottomSheetModal>
</View>
)
}
export default AddPost
This post has been updated.
I guess since we are dealing with images and not an object array that's why index wasnt working. So i changed index with items and decided to us the .filter method instead of .splice. And it worked.
const deleteMedia = (item) => {
setMedia((prev) => prev.filter((el) => el !== item));
console.log(item)
};
You need to declare remove media outside the function delete media because everytime you call delete media. You are reinitalizing the removeMedia useState to the original media values. I did not test these codes, but from the codes I can clearly tell that you are just reinitalizing remove media back to its original value. Try this
let removeMedia=[...media];
const deleteMedia = (index) => {
removeMedia.splice(index, 1);
setMedia(removeMedia)
};

flatlist and scrollView is not working properly

I'm new in react-native. On one of my screen I'm using flatlist on 4 places but the last flatlist which is displaying at the bottom of screen is not scrolling so I add the scrollView then its working fine but displaying me that error
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
code
const Header = () => {
return (
<View>
<SafeAreaView>
<View style={styles.sellersheaderWrapper}>
<View style={styles.sellersheaderTitle}>
<Text style={styles.sellersheaderTitleText}>
Featured Sellers
</Text>
</View>
<View>
{
isFeatureSeller == '' ?
<View style={[styles.noSpecialOfferCard, {paddingVertical:hp('2%')}]} >
<Text style={[styles.noSpecialOfferCardText, {fontSize:hp('2%')}]}>Currently, No Feature Sellers</Text>
</View>
:
<View>
<FlatList
data={isFeatureSeller}
renderItem={renderCategoryItem}
keyExtractor={item => item.id}
horizontal={true}
showsHorizontalScrollIndicator={false}
/>
</View>
}
</View>
</View>
</SafeAreaView>
<View style={styles.searchWrapper}>
<View style={styles.dobregisterFormWrapperText}>
<TextInput
style={styles.dobregisterInputStyleText}
value={search}
onChangeText={(text) => searchFilterFunction(text)}
onClear={(text) => searchFilterFunction('')}
placeholder="Search ..."
/>
<View>
<SearchIconSvg />
</View>
</View>
</View>
</View>
);
};
const Footer = () => {
return (
<View>
<View style={styles.specialOfferCardWrapper}>
<View style={styles.specialOfferCardTextWrapper}>
<Text style={styles.specialOfferCardText}>Special Offer Cards</Text>
</View>
{isSpecialCards == '' ? (
<View style={styles.noSpecialOfferCard}>
<Text style={styles.noSpecialOfferCardText}>
No Special Offer cards
</Text>
</View>
) : (
<FlatList
data={isSpecialCards}
renderItem={renderCards}
keyExtractor={(item, index) => index.toString()}
horizontal={true}
showsHorizontalScrollIndicator={false}
style={styles.specialCards}
/>
)}
<View
style={[
styles.specialOfferCardTextWrapper,
{paddingBottom: isFeatureSeller == '' ? hp('17%') :hp('10%') },
]}>
<Text style={styles.specialOfferCardText}>Cards</Text>
<FlatList
data={isCard}
renderItem={renderNormalCards}
keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
scrollEnable={true}
/>
</View>
</View>
</View>
);
};
const MainData = () => {
return(
<View>
{search == '' ? (
<ScrollView>
<View >
<Header />
<Footer />
</View>
</ScrollView>
) : (
<View >
<FlatList
data={filteredDataSource}
renderItem={renderCategoryItemSearch}
keyExtractor={(item, index) => index.toString()}
ListHeaderComponent={Header}
/>
</View>
)}
</View>
)
}
return (
<View style={styles.container}>
{
loading == true ?
<View style={{marginVertical:hp('45%')}} >
<ActivityIndicator size="large" color={colors.primary} />
</View>
:
<MainData/>
}
<View style={styles.bottomNavWrapper}>
<TouchableOpacity
style={styles.storeWrapper}
onPress={() => navigation.navigate('BuyerDashboard')}>
<View style={styles.storeIcon}>
<DashboardReverseSvg />
</View>
</TouchableOpacity>
<View style={styles.dashboardWrapper}>
<View style={styles.dashboardIcon}>
<BuyerStoreReverseSvg />
</View>
<View style={styles.dashboardText}>
<Text style={styles.dashboardTextfont}>Storefront</Text>
</View>
</View>
</View>
</View>
);
};
export default Store;
I want to scroll at here.
<ScrollView>
<View >
<Header />
<Footer />
</View>
</ScrollView>
You can use nestedScrollEnabled prop on your FlatList component
https://reactnative.dev/docs/scrollview#nestedscrollenabled

How can I change a button when I select a item in a flatlist

I saw some questions about it here on SO, but none of them work for me.
So my problem is when I click on the button "Add Friend" all of the buttons change to "remove", and I want to change only the button that I click
Normal
When I click in any button, all of them change to "remove"
My Code is:
export default class Friends extends Component {
state = {
visible: false,
userInfo: null,
requested: null
}
buttonAdd() {
if (this.state.requested === null) {
return (
<View style={styles.buttonContainer}>
<TouchableOpacity style={[styles.button, styles.add]} onPress={() => this.setState({ requested: true })}>
<Text style={{ color: "#fff", fontWeight: "bold" }}>Add Friend</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.remove]}>
<Text style={{ color: "#050505", fontWeight: "bold" }}>Remove</Text>
</TouchableOpacity>
</View>
)
} else if (this.state.requested === true) {
return (
<View style={styles.buttonContainer}>
<TouchableOpacity style={[styles.button, styles.remove, styles.removeBig]} onPress={() => this.setState({ requested: false })} >
<Text style={{ color: "#050505", fontWeight: "bold" }}>Remove</Text>
</TouchableOpacity>
</View>
)
} else {
return (
<View style={styles.buttonContainer}>
<TouchableOpacity style={[styles.button, styles.add]} onPress={() => this.setState({ requested: true })}>
<Text style={{ color: "#fff", fontWeight: "bold" }}>Add Friend</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.remove]}>
<Text style={{ color: "#050505", fontWeight: "bold" }}>Remove</Text>
</TouchableOpacity>
</View>
)
}
}
render() {
const inform = this.props.info
return (
<View>
<FlatList
data={inform}
keyExtractor={item => item.id.toString()}
ListHeaderComponent={this.topComponents()} //ignore this //with the ListHeaderComponent the components will not repeat
renderItem={({ item }) => (
<View style={styles.peopleContainer}>
<TouchableOpacity onPress={() => this.setState({ visible: true, userInfo: item })}> <Image source={item.photo} style={styles.photo} />
</TouchableOpacity>
<View style={styles.geralContent}>
<Text style={styles.name}>{item.name}</Text>
{this.buttonAdd()}
</View>
</View>
)}
/>
</View>
);
}
}
Sorry about the huge code.
There may be several approaches to handle this. This is just my approach to handle this specific issue.
Currently, all of the items sharing the same state. That means if any of the items update the component state, it will affect all the items of the FlatList. To overcome this problem we need to refactor the code so every item has its own state. Here is a snippet of how to do that and fix the problem
const FriendItem = ({ item, onPressPhoto }) => {
const [requested, setRequested] = React.useState(false)
return (
<View style={styles.peopleContainer}>
<TouchableOpacity onPress={() => onPressPhoto({ visible: true, userInfo: item })}>
<Image source={item.photo} style={styles.photo} />
</TouchableOpacity>
<View style={styles.geralContent}>
<Text style={styles.name}>{item.name}</Text>
<View style={styles.buttonContainer}>
{!requested ?
<TouchableOpacity style={[styles.button, styles.add]} onPress={() => setRequested(true)}>
<Text style={{ color: "#fff", fontWeight: "bold" }}>Add Friend</Text>
</TouchableOpacity>
:
null
}
<TouchableOpacity style={[styles.button, styles.remove]}>
<Text style={{ color: "#050505", fontWeight: "bold" }}>Remove</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
}
export default class Friends extends Component {
state = {
visible: false,
userInfo: null,
}
onPressPhoto = ({ visible, userInfo }) => {
//write your logic here to handle on click
}
render() {
const inform = this.props.info
return (
<View>
<FlatList
data={inform}
keyExtractor={item => item.id.toString()}
ListHeaderComponent={this.topComponents()} //ignore this //with the ListHeaderComponent the components will not repeat
renderItem={({ item }) => <FriendItem item={item} onPressPhoto={this.onPressPhoto} />}
/>
</View>
);
}
}

How can I collapse Item pressed on arrays - react native?

I have a list of cards,
when pressed to any of them, I want to Increase hight for that card,
So I use layoutAnimation to handle this case because when I use Animated API from RN, I got an error when setNativeDrive "height"
Anyway,
In my case, it increases height for every card in the list,
So how can I solve it?
Code snippet
Live Demo
const OpenedAppointments = ({slideWidth}) => {
const [currentIndex, setCurrentIndex] = React.useState(null);
const [cardHeight, setCardHeight] = useState(140);
const collapseCard = (cardIndex) => {
setCurrentIndex(cardIndex);
currentIndex === cardIndex
? (LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut),
Animated.spring(),
setCardHeight(200))
: (LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut),
Animated.spring(),
setCardHeight(140));
};
const renderItems = (item, index) => {
return (
<TouchableOpacity
delayPressIn={0}
onPress={() => collapseCard(index)}
key={item.id}>
<Animated.View
style={[
styles.itemContainer,
{
height: cardHeight,
},
]}>
<View style={styles.headerContainer}>
<View style={styles.imgContainer}>
<Image
resizeMode="cover"
style={styles.img}
source={{uri: item.vendorInfo.vendorImg}}
/>
</View>
<View style={{width: '80%'}}>
<View style={styles.titleContainer}>
<Text numberOfLines={1} style={styles.vendorName}>
{item.vendorInfo.name}
</Text>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text style={styles.rateText}>{item.vendorInfo.rate}</Text>
<AntDesign name="star" size={18} color="#262626" />
</View>
</View>
<View style={styles.socialContainer}>
<View
style={{
width: 32,
height: 32,
backgroundColor: '#000',
borderRadius: 5,
}}
/>
</View>
</View>
</View>
<View style={styles.footer}>
<Text style={styles.serviceName}>
{item.serviceName}
</Text>
<Text style={styles.price}>
{item.price}
</Text>
</View>
// this will appeared when pressed to card "Footer Card"
<View>
<View style={styles.line} />
<View style={styles.editFooter}>
<View style={styles.dateContainer}>
<MemoCalender
style={styles.calenderIcon}
size={26}
color="#000"
/>
<View style={styles.dateBox}>
<Text style={styles.dateText}>{item.date}</Text>
<Text style={styles.dateText}>{item.time}</Text>
</View>
</View>
</View>
</View>
</Animated.View>
</TouchableOpacity>
);
};
return(
<>
{Data.opened.map((item, index) => renderItems(item, index))}
</>
);
}
Change this:
<Animated.View
style={[
styles.itemContainer,
{
height: cardHeight,
},
]
>
{...}
</Animated.View>
by
<Animated.View
style={[
styles.itemContainer,
{
height: currentIndex === index ? cardHeight : 140,
},
]
>
{...}
</Animated.View>
If you want to be more efficient, the default height of your card, define it in a constant (ex: const = DEFAULT_CARD_HEIGHT = 140) and use this constant wherever you use 140 as card height

Unable to show multiple images in react native

I am working on a react native application. I have to show multiple images. My code is:
render() {
if (!this.props.data) {
return(<Text style={styles.noIMG}>Keine Bilder vorhanden</Text>)
}
return (
<View>
<View style={styles.view}>
{
(
this.props.data == '' ||
this.props.data == null ||
this.props.data == undefined
) ? null :
this.props.data.map(img => {
console.log(img.image);
console.log("Image displayed");
return(
<TouchableHighlight
key={this.uuidv4()}
onPress={()=>{
this.setState({zoom: img.image})
}}
>
<Image
style={styles.imagePreview}
source={{uri: img.image}}
/>
</TouchableHighlight>)
})
}
</View>
{ this.state.zoom ?
<Card>
<PinchZoomView scalable={false}>
<FitImage resizeMode="contain" source={{uri: this.state.zoom}}/>
</PinchZoomView>
<TouchableOpacity
style={styles.btn}
onPress={() => this.deleteImage(this.state.zoom)}>
<Text style={{color:'white'}}>Delete Image</Text>
</TouchableOpacity>
</Card> :
<View style={styles.container}><Text>Bild zum vergrößern antippen.</Text></View>
}
</View>
);
}
I do get two images in "props.data" but on screen only one image is displayed. The css code is:
const styles = StyleSheet.create({
imagePreview:{
width: 100,
height: 100,
margin: 5
}
});
render() {
return (
<View style={{ flex: 1, flexDirection:'row'}}>
{data.map((value, i) => {
return (
<View key={i}>
<TouchableOpacity>
<Image
source={{ uri: value.imageUrl }}
style={{ width: 50, height: 50 }}
resizeMode={"stretch"}
/>
</View>
</TouchableOpacity>
);
})}
</View>
);
}
Try using a FlatList
<FlatList
data={this.props.data}
extraData={this.state}
renderItem={({ item }) => {
return (
<View>
<TouchableOpacity onPress={() => this.setState({zoom: img.image})}>
<Image
source={{ uri: item.image }}
PlaceholderContent={<ActivityIndicator />}
/>
</TouchableOpacity>
</View>
)
}}
keyExtractor={(item, index) => index.toString()}
/>

Categories