React native custom view - reactjs

I am developing an app where the user adds item name, description, quantity and image url and it gets stored in AsyncStorage. I have made it ready and it looks like this:
Now i am trying to fetch it from Asyncstorage and i Get a 2D array. Here is the code:
myA1 = await AsyncStorage.getItem('key1');
var ee=JSON.parse(myA1); //ee is 2D array
It looks like this
[[imgurl1 itemname1, desc1, quantity1],
[imgurl2 itemname2, desc2, quantity3],
[imgurl3 itemname3, desc2, quantity3],
[imgurl4 itemname4, desc2, quantity3]]
How can I acheive this??
I am beginner for react native
I want to display it as follows
:

You van use FlatList for rendering a list of data. It has a renderItem prop that you can pass a view to render each row of data like that. Put your data in an state (data in this code). Here is an example:
makeContentItem(item) {
return (
<TouchableOpacity
onPress={() => {
//Do sth when clicking on a row
}}>
<View style={{ width: '90%', height: 140, marginBottom: 5, borderRadius: 2, backgroundColor: 'white' }}>
<View style={{ flex: 1, flexDirection: 'row' }}>
<Image style={{ width: 40, height: 40 }} source={require(item.imgurl)} />
<View>
<Text>{item.itemname}</Text>
<Text>{item.desc}</Text>
<Text>{item.quantity}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
render() {
return (
<FlatList
data={this.state.data}
renderItem={({ item, index }) => {
return this.makeContentItem(item)
}
/>
)
}
You can change the style to achieve what you want. also you can take a look at FlatList
I hope it will help

renderEditAndClose() {
return(
<View style={{flex:1, flexDirection: "row", justifyContent: "flex-end"}}>
{this.renderEditImage()}
{this.renderCloseImage()}
</View>
);
}
renderImageAndItemData(item: Object) {
return(
<View style={{flex:1, flexDirection:"row"}}>
{this.renderItemImage()}
{this.renderItemData(item)}
</View>
);
}
renderItemImage(width: number, height: number, url: string) {
return (
<Image style={{ width: width, height: height }} source={{uri: url}} />
);
}
renderItemData(item: Object) {
return(
<View>
<View style={{flex: 1, flexDirection: "row", justifyContent: "space-around"}}>
<Text>{item.name}</Text>
<Text>{item.quantity}</Text>
</View>
<Text>{item.description}</Text>
</View>
);
}
renderRow(item: Object) {
return() {
<View>
{this.renderEditAndClose()}
{this.renderImageAndItemData(item)}
</View>
}
}
render() {
return (
<FlatList data={ee}
renderItem={(item) => this.renderRow(item)} />
);
}

Related

FlatList renderItem problem with return value

I am new to react native and I do not know how it works yet but I want to return cosnt Card in renderItem.I want the flat list to return the data I retrieve via axios from API. API has data for two products that it wants to throw into const Card. The problem is that I do not know what to return in renderItem. At the bottom I put the code without style to better see what I mean. I think the problem is that const Card can't see the data retrieved by AXIOS.
code:
const HomeScreen = ({navigation}) => {
const [data, setData] = useState([])
useEffect(() => {
axios.get('https://api.npoint.io/e3d714eb88eb75f37f29')
.then(({ data }) => {
console.log("defaultApp -> data", data.products)
setData(data.products)
})
.catch((error) => console.error(error))
}, []);
const Card = () => {
return (
<TouchableOpacity activeOpacity={0.8}>
<View style={style.card}>
<View style={{
flexDirection: "row",
justifyContent: 'center',
alignItems: 'center'
}}>
<Text style={{fontWeight: "bold", fontSize: 17, marginTop: 5}}>
{item.description}
</Text>
</View>
<View style={{
flexDirection: "row",
marginTop: 5,
justifyContent: 'center',
alignItems: 'center'
}}>
<Text style={{
fontSize: 18,
fontWeight: 'bold',
color: COLORS.dark_red
}}>
{item.price}
</Text>
</View>
</View>
</TouchableOpacity>
);
}
return (
<SafeAreaView
style={{
flex: 1,
paddingHorizontal: 20,
backgroundColor: COLORS.back_color,
}}>
<FlatList
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
marginTop: 10,
paddingBottom: 20
}}
data={data}
keyExtractor={({id}, index) => id}
renderItem={({item}) => {
return <Card product={item}/>; //here ?!?
}}
/>
</SafeAreaView>
);
};
export default HomeScreen;
I think you need to pass props into the Card component. Try passing item in as a prop like this:
const Card = ({ item }) => {
return (
<TouchableOpacity activeOpacity={0.8}>
...
</TouchableOpacity>
);
};
Then pass in that item prop when you render the Card component from the FlatList.
<FlatList
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
marginTop: 10,
paddingBottom: 20,
}}
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => {
return <Card item={item} />; // changed this to take in item prop
}}
/>;

React Native: how can i press on flatlist item and open specific screen for that item?

I want to press on a flat item and then open a new screen which has details from the item but how is the best way to do that?
should I make a modal and give it the details?
or should I make a new screen for every item?
const renderRecipe = ({ item }) => {
return (
<View style={styles.item}>
<Image style={styles.image} source={{ uri: item.image }}>
</Image>
<Text style={{
color: '#00aecc', fontSize: 18,
marginTop: 15
}}>{item.label}</Text>
<View style={{ alignItems: "center" }}>
<Text style={{ color: '#fff', marginTop: 100, fontSize: 20 }}>Zutaten:</Text>
<Text style={{ color: '#00aecc', fontSize: 18, marginTop: 15 }}>{item.id}</Text>
</View>
</View >
)
}
return (
<View style={styles.container}>
{isLoading && <View style={{ height: "100%", width: "100%" }}><ActivityIndicator style={styles.loading} color='#00aecc' size="large" /></View>}
<FlatList
data={userRecipes}
renderItem={renderRecipe}
keyExtractor={(item) => item.id}>
</FlatList>
</View >
);
This is my item now how can I do what I want.
I will try to explain. You have two screens Home and Details.
Assume in your Home screen your Flatlist. So when you click to item on Flatlist you will navigate to Details screen with items details.That's it!
You can also do this with modal. But here it depends on requirement. There is not any perfect solution. Based on case scenario you do it.
In your case I will do followings.
First I will import TouchableOpactiy and useNavigation.
import {TouchableOpactiy} from 'react-native'
import { useNavigation } from '#react-navigation/native';
Then I will use it to my flatlist items.
Home Screen
const Home = () => {
const navigation = useNavigation();
const renderRecipe = ({ item }) => {
return (
<TouchableOpactiy onPress={()=> navigation.navigate('Details', {item} )}>
<View style={styles.item}>
<Image style={styles.image} source={{ uri: item.image }}>
</Image>
<Text style={{
color: '#00aecc', fontSize: 18,
marginTop: 15}}>{item.label}</Text>
<View style={{ alignItems: "center" }}>
<Text style={{ color: '#fff', marginTop: 100, fontSize: 20 }}>Zutaten:
</Text>
<Text style={{ color: '#00aecc', fontSize: 18, marginTop: 15 }}>{item.id}
</Text>
</View>
</View >
</TouchableOpactiy>
)
}
return (
/*your flalist*/
)
}
Details Screen
const Details = ({ route, navigation ) => {
const { item } = route.params;
return (
<Text>{item.label}</Text>
)
}

How to pass numeric input values of components inside flatlist from modal screen to main component screen?

I have a list of items inside a flatlist with numeric inputs of each one of them as follows
My code for the flatlist is as follows:
const BedRoomModal = () => {
return (
<View style={{flex: 1}}>
<ScrollView>
<Text style={Styles.headerText}>Bedroom 1</Text>
<View style={Styles.container}>
<FlatList
data={bedData.BED}
renderItem={renderItem}
keyExtractor={(item) => item.BED_ID}
/>
</View>
</ScrollView>
<TouchableOpacity
onPress={() => BedRoomSave()}
style={{
alignSelf: 'flex-end',
right: 5,
position: 'absolute',
bottom: 10,
}}>
<View
style={{
backgroundColor: '#20B2AA',
alignSelf: 'flex-end',
padding: 10,
}}>
<Text style={{fontSize: 15, fontWeight: 'bold', color: '#fff'}}>
SAVE
</Text>
</View>
</TouchableOpacity>
</View>
);
};
renderItem is as follows:
const renderItem = ({item,index}) => {
return (
<>
<View
style={{
marginBottom: 24,
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Text style={Styles.checklistTitle}>{item.BED_TITLE}</Text>
<NumericInput
value={bed[index]}
onChange={(value) => bedDataFunction(value,index)}
totalWidth={100}
totalHeight={35}
iconSize={22}
step={1}
valueType="integer"
textColor="#B0228C"
iconStyle={{color: 'black'}}
rightButtonBackgroundColor="#fff"
leftButtonBackgroundColor="#fff"
minValue={0}
/>
</View>
<View style={Styles.itemSeparator}></View>
</>
);
};
bedDataFunction:
const bedDataFunction=(value,id)=>{
console.log('VALUE')
console.log(value)
console.log('ID')
console.log(id)
}
The states that I have used are:
const [bed, setBed] = useState([]);
I get the value inside the console of my onchange function but now I need to take that value and display it on screen? could anyone tell what am I doing wrong here?
Any suggestion would be welcomed, am stuck since long now, hopefully would recieve help, thank you.
Let me know if anything is required for better understanding of the code.

How to check FlatList if its null or not

How can I check the FlatList if it's null or not and if null I will display something like No Available Booking's? I have tried the code below using short hand operator but it's not working.
{bookings == null ?
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.title}>No Availabe Booking's Yet!</Text>
</View>
:
<FlatList
data={bookings}
renderItem={flatListItem}
refreshing={refresh}
onRefresh={refreshSummary}
keyExtractor={item => item._id}
/>
}
Instead of making checks on the data and conditionally rendering the FlatList and the empty list view, you can use the existing prop provided by the FlatList i.e. ListEmptyComponent. You can read more about the FlatList and its other props in the official documentation of the React-Native here.
A typical usage of the ListEmptyComponent could be:
import React, { PureComponent } from 'react';
import { Text, View, StyleSheet, FlatList } from 'react-native';
export default class BookingsList extends PureComponent {
state = {
bookings: [
// {
// _id: 1,
// title: 'I am a booking'
// }
],
refreshing: false
};
keyExtractor = (item) => String(item._id);
refreshSummary = () => {};
renderBookings = ({ item }) => (
<View style={styles.bookingCard}>
<Text style={styles.title}>{item.title}</Text>
</View>
);
renderItemSeparatorComponent = () => <View style={styles.separator} />;
//render the empty list component in case the data array for the FlatList is empty
renderListEmptyComponent = () => (
<View style={styles.emptyListContainer}>
<Text style={styles.noBookingsFound}>
No Availabe Booking's Yet!
</Text>
</View>
);
render() {
const { bookings, refreshing } = this.state;
return (
<FlatList
data={bookings}
refreshing={refreshing}
renderItem={this.renderBookings}
onRefresh={this.refreshSummary}
ListEmptyComponent={this.renderListEmptyComponent} //<==== here
ItemSeparatorComponent={this.renderItemSeparatorComponent}
contentContainerStyle={styles.list}
keyExtractor={this.keyExtractor}
/>
);
}
}
const styles = StyleSheet.create({
bookingCard: {
backgroundColor: 'white',
padding: 10,
marginTop: 2,
borderBottomWidth: 0.5
},
title: {
fontSize: 16,
fontWeight: 'bold'
},
emptyListContainer: {
alignItems: 'center',
justifyContent: 'center',
},
noBookingsFound: {
fontSize: 16,
},
separator: {
height: 15
},
list: {
paddingHorizontal: 15,
paddingBottom: 40
}
});
Would booking not be an Array for a flatlist ?
return (
{bookings !== undefined && bookings.length > 0 ?
<View>
<FlatList
data={bookings}
renderItem={flatListItem}
refreshing={refresh}
onRefresh={refreshSummary}
keyExtractor={item => item._id}
/>
</View>
:
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.title}>No Availabe Booking's Yet!</Text>
</View>
}
);
** Edited as I think I missed your point!
You can return a conditional view in React Native as follows
return (
<View>
{state.someVar == null ?
(<ACOMPONENT />)
:
(<ADIFFCOMPONENT />)
}
</View>
);
Hopefully that's a better response.
u can use listemptycomponent
Rendered when the list is empty. Can be a React Component Class, a render function, or a rendered element.
https://reactnative.dev/docs/flatlist#listemptycomponent
<FlatList
data={bookings}
renderItem={flatListItem}
refreshing={refresh}
onRefresh={refreshSummary}
keyExtractor={item => item._id}
ListEmptyComponent={<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.title}>No Availabe Booking's Yet!</Text>
</View>}
/>
{ bookings && Array.isArray(bookings) ? (
<FlatList
data={bookings}
renderItem={flatListItem}
refreshing={refresh}
onRefresh={refreshSummary}
keyExtractor={item => item._id}
/>
) : (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.title}>No Availabe Booking's Yet!</Text>
</View>
)
}

flexDirection: 'row' is not working in FlatList

I'm trying to get below output but flexDirection: 'row' is not working properly. Please can anyone explain me how to get below output. Any help is appreciated.
**Required output: **
My output:
My code is:
_renderItem(rowData) {
return(
<View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap'}}>
<View style={{margin: 2, width: '24%', backgroundColor: '#fff', borderWidth: 1, borderColor: '#aaa'}}>
<TouchableOpacity activeOpacity={0.9} style={{height: 190}}>
<Image source={{uri: rowData.item.images[0].src}} style={{height: '100%', width: '100%'}}/>
</TouchableOpacity>
<View style={{padding: 5}}>
<TouchableOpacity activeOpacity={0.9} style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<View>
<CapitalizedText style={{color: '#666', fontSize: 14}}>{rowData.item.title}</CapitalizedText>
<Text style={{fontSize: 15, color: '#666', justifyContent: 'center', alignItems: 'center'}}>{'₹' + rowData.item.variants[0].price}</Text>
</View>
<Icon size={24} color="#aaa" name="turned-in-not" />
</TouchableOpacity>
<CapitalizedText style={{fontSize: 14, color: '#bbb'}}>Printed Top</CapitalizedText>
</View>
</View>
</View>
);
}
render() {
return(
<View>
{
this.state.product_detail.length <= 0 ?
<ActivityIndicator color = '#bc2b78' size = "large" style={{alignItems: 'center', justifyContent: 'center'}} />
:
<FlatList
keyExtractor = {( item, index ) => index }
data = { this.state.product_detail }
renderItem = {(rowData) => this._renderItem(rowData)}
ListFooterComponent = { this._render_Footer }
/>
}
</View>
);}
Thank you.
Use numColumns property in flatList to align text items of flatList in a row like
let numColumns=5;
<FlatList numColumns={numColumns}/>
Please see this one if is work for you https://snack.expo.io/SywBhpMgW
You only have one child element (another View element) of the view which sets flexDirection to row. FlexDirection only has influence on its direct children.

Resources