Hi guys I am trying to display data from an object to my flatlist here it is
import {ItemLists} from '../data/ItemLists';
const ListItem = ({item}) => {
return (
<View style={{margin: 10}}>
<Image source={{
uri: item.uri,
}}
style={{width:200,height:200}}
resizeMode="cover"
/>
<Text style={{margin:5}}>{item.text}</Text>
</View>
)
};
and here's my dummy data
export const ItemLists = [
{
title: 'Hot Deals',
data: [
{
"key": 1,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-01"
},
{
"key": 2,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-02"
},
{
"key": 3,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-03"
},
{
"key": 4,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-04"
},
{
"key": 5,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-05"
},
{
"key": 6,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-06"
},
{
"key": 7,
"text": "Title of Food",
"uri": "../../Assets/Images/featured-restau-07"
}
]
}
];
Now here's how I use my FlatLis
<ScrollView>
//... other codes
//... other codes
<View style={styles.HotDealsContainer}>
<View style={styles.HotDealItemContainer}>
<Text style={styles.HotDealTitle}>Hot Deals</Text>
<View style={styles.HotDealsItem}>
<FlatList
horizontal
data={ItemLists}
keyExtractor={(item) => item.key}
renderItem={({item}) => <ListItem item {...item}/>}
/>
</View>
</View>
</View>
</ScrollView>
HotDealsContainer:{
width:'100%',
height:200,
backgroundColor: 'green',
},
HotDealItemContainer:{
marginTop: -135,
marginLeft: 20,
width:Dimensions.get('window').width / 2 * 2 - 40,
height:150,
backgroundColor: 'blue',
},
HotDealsItem:{
flex:1,
justifyContent:'space-between',
flexDirection:'row',
},
HotDealTitle:{
color:'#000',
fontSize:18,
fontWeight: 'bold',
},
The current problem I am facing right now is that it won't display a single thing on the screen . Can someone point out what I am doing wrong ?
Your ItemLists has only one item which has title and data array. If you want to render that data you have to pass only that array:
<FlatList
horizontal
data={ItemLists[0].data}
keyExtractor={(item) => item.key}
renderItem={({item}) => <ListItem item {...item}/>}
/>
The second problem I noticed is that you don't pass the item property to . What you want to do is next:
<ListItem item={item} />
It will be better for readability purpose to store that array of data in a separate variable rather than in an object which is in another array
Related
I want to select one item from each ListItem. But the problem is that I can only choose one item at a time. I have used multiselect, but the problem is there is that multiple items could be selected from each section item.
**
I want to access one data from every list in react native listitem.I
want to select one item from each ListItem. But the problem is that I
can only choose one item at a time. I have used multiselect, but the
problem is there is that multiple items could be selected from each
section item.I have used flatlist then in renderitem I have used
listItem.
**
ProductAttributes:Object {
"Id": 9,
"Name": "Size",
"Values": Array [
Object {
"ColorSquaresRgb": null,
"CustomProperties": Object {},
"FullSizePictureUrl": null,
"Id": 21,
"IsPreSelected": false,
"Name": "8",
"PictureId": 0,
"PictureUrl": null,
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
Object {
"ColorSquaresRgb": null,
"CustomProperties": Object {},
"FullSizePictureUrl": null,
"Id": 22,
"IsPreSelected": false,
"Name": "9",
"PictureId": 0,
"PictureUrl": null,
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
],
}
ProductAttributes: Object {
"Id": 10,
"Name": "Color",
"Values": Array [
Object {
"ColorSquaresRgb": "#663030",
"CustomProperties": Object {},
"FullSizePictureUrl": "img1",
"Id": 25,
"IsPreSelected": true,
"Name": "Red",
"PictureId": 53,
"PictureUrl": "img2",
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
Object {
"ColorSquaresRgb": "#363656",
"CustomProperties": Object {},
"FullSizePictureUrl": "img3",
"Id": 26,
"IsPreSelected": false,
"Name": "Blue",
"PictureId": 54,
"PictureUrl": "img4",
"PriceAdjustment": null,
"PriceAdjustmentValue": 0,
},
],
}
And the UI is
<FlatList
data={this.state.product_attributes2}
ListHeaderComponent={null}
renderItem={({ item, index }) => {
console.log("ProductAttributes: ", item);
return (
<>
<ListItem.Accordion
style={{ height: 50 }}
content={
<>
<Iconsss
name="filter-menu"
size={20}
style={{ marginRight: 10 }}
/>
<ListItem.Content>
<ListItem.Title>{item.Name}</ListItem.Title>
</ListItem.Content>
</>
}
isExpanded={this.state.expanded}
onPress={() => {
this.setState({ expanded: !this.state.expanded });
}}
>
<View
style={{
borderTopWidth: 1,
borderColor: "rgba(38, 38, 38,0.8)",
}}
>
{item?.Values?.map((l, i) => {
return (
<ListItem
key={i}
onPress={() => {
console.log(l.IsPreSelected);
this.setState({
select_choice: true,
choice_name: l.Name,
// IsPreSelected:l.IsPreSelected,
});
}}
bottomDivider
Checkbox
>
<ListItem.CheckBox
// checked={this.state.IsPreSelected}
checked={l.IsPreSelected === true ? true : false}
onPress={() =>
this.setState({ IsPreSelected: !l.IsPreSelected })
}
/>
<ListItem.Content>
<ListItem.Title
style={{ color: "rgba(38, 38, 38,1)" }}
>
{l.Name}
</ListItem.Title>
</ListItem.Content>
{l?.ColorSquaresRgb === null ? null : (
<View
style={{
backgroundColor: l?.ColorSquaresRgb,
height: 20,
// width:20,
borderRadius: 20,
flex: 0.3,
justifyContent: "center",
// alignItems:"center",
}}
/>
)}
{l?.PictureUrl === null ? null : (
<Image
source={{ uri: l.PictureUrl }}
style={{
flex: 0.7,
resizeMode: "contain",
height: 50,
}}
/>
)}
</ListItem>
);
})}
</View>
</ListItem.Accordion>
</>
);
}}
keyExtractor={(item, index) => {
return index.toString();
}}
ListFooterComponent={null}
/>
for some reason the component is not Re-Rendering on the setDependent, i have added the setPerson and the console does log the item without that one deleted, but is not updating the component. please see code below, as of right now is loading with no problem from the server but at the moment of deletion it does send the command to delete but the list does not get re-render, the "person" still listed on the FlatList
const RemoveDependent = ({ onPress }) =>
(
<TouchableWithoutFeedback onPress={onPress}>
<View style={{
backgroundColor: colors.dangerLight,
//height: 70,
width: 70,
//borderRadius: 35,
right:-5,
justifyContent: 'center',
alignItems: 'center'
}}>
<MaterialCommunityIcons name="trash-can" size={30} style={{ color: colors.white }} />
</View>
</TouchableWithoutFeedback>
)
function FamilyScreen(props) {
const [person, setDependent] = useState(dependents);
const handleRemove = onDependent => {
console.log(person.filter(d => d.id !== onDependent.id));
setDependent(person.filter((d) => d.id !== onDependent.id));
}
return (
<View style={{ backgroundColor: colors.white, flex: 1 }}>
<Image
source={require('../assets/familyBg.jpeg')}
style={styles.image}
resizeMode="cover"
/>
<View style={styles.details}>
<RevText style={styles.title}>Family Plan</RevText>
<RevText style={styles.description}>Description here</RevText>
</View>
<FlatList
data={dependents}
keyExtractor={personal => personal.id.toString()}
renderItem={({ item }) => (
<ListItem
onPress={() => handleRemove(item) }
title={item.name}
subTitle={item.type}
image={item.image}
renderRightActions={() => (<RemoveDependent onPress={() => handleRemove(item)} />) }
ItemSeparatorComponent={() => (<View style={{ width: '96%', left: 5, borderBottomColor: 'red', borderBottomWidth: 1 }} />)}
/>
)}
/>
</View>
);
}
Object {
"id": 1014,//REMOVED ID WHEN CLICKED
"image": 19,
"name": "Person 1",
"type": "Child",
}
Array [ //NEW ARRAY
Object {
"id": 1015,
"image": 19,
"name": "PERSON 2",
"type": "Child",
},
Object {
"id": 1016,
"image": 19,
"name": "PERSON 3",
"type": "Child",
},
Object {
"id": 1017,
"image": 19,
"name": "PERSON 4",
"type": "Child",
},
]
The main problem with this code is that your are altering a state object directly. You should treat all state objects as if they are immutable.
change
setDependent(person.filter((d) => d.id !== onDependent.id));
with
setDependent([...person.filter((d) => d.id != onDependent.id)]);
I run a fetch from a server that returns an object that you can see an exemple of here:
{
"info": [
{
"ID": "1",
"name": "name sample",
"description": "description sample",
"img": "0",
"price": "14.00",
"Omega": "0",
"categories": []
}
],
"categories": [
{
"ID": "1",
"name": "base",
"min": "1",
"max": "1",
"actual": "2",
"options": [
{
"ID": "1",
"name": "peanuts",
"supplement": "1",
"checked": "true"
},
{
"ID": "2",
"name": "cheesecake",
"supplement": "0",
"checked": "false"
},
{
"ID": "9",
"name": "carrots",
"supplement": "3",
"checked": "true"
}
]
},
{
"ID": "2",
"name": "enhancer",
"min": "1",
"max": "1",
"actual": "0",
"options": [
{
"ID": "3",
"name": "mojito",
"supplement": "3",
"checked": "false"
}
]
},
{
"ID": "3",
"name": "berry",
"min": "1",
"max": "3",
"actual": "1",
"options": [
{
"ID": "10",
"name": "banana",
"supplement": "0",
"checked": "true"
},
{
"ID": "11",
"name": "blueberry",
"supplement": "2",
"checked": "false"
}
]
},
{
"ID": "4",
"name": "special",
"min": "1",
"max": "4",
"actual": "0",
"options": [
{
"ID": "12",
"name": "moon",
"supplement": "1",
"checked": "false"
}
]
},
{
"ID": "8",
"name": "ultima",
"min": "0",
"max": "1",
"actual": "1",
"options": [
{
"ID": "13",
"name": "ultimo",
"supplement": "5",
"checked": "true"
}
]
}
]
}
and then to parse all this result into a list of checkboxes i use this code:
<FlatList
data={data.categories}
keyExtractor={(item, index) => item.name + item.ID}
// style={{marginBottom: 200}}
renderItem={({ item }) => (
<View
style={{
marginTop: 0,
marginLeft: 0,
marginRight: 0,
marginBottom: 0,
flexDirection: "column",
}}
>
<View
style={{
paddingTop: 10,
paddingBottom: 0,
flexDirection: "column",
}}
>
<View
style={{
paddingTop: 10,
paddingBottom: 10,
flexDirection: "column",
borderTopColor: "lightgrey",
borderTopWidth: 1,
borderBottomColor: "lightgrey",
borderBottomWidth: 1,
marginTop: 10,
}}
>
<Text
style={{
fontSize: 18,
color: "black",
textAlign: "left",
paddingHorizontal: 10,
fontWeight: "bold",
}}
>
{item.name}
</Text>
<View
style={{
flexDirection: "row",
}}
>
{item.min > "0" ? (
<Text
style={{
fontSize: 12,
color: "red",
textAlign: "left",
paddingLeft: 10,
}}
>
Requis
</Text>
) : (
<Text></Text>
)}
<Text
style={{
fontSize: 12,
color: "black",
textAlign: "left",
paddingHorizontal: 5,
}}
>
Choose between {item.min} and {item.max} options
</Text>
</View>
</View>
<FlatList
data={item.options}
style={{}}
keyExtractor={(item, index) => item.name + item.ID}
renderItem={({ item: innerData, index }) => (
<View>
<View style={styles.optionView}>
<CheckBox
containerStyle={{ marginLeft: 0, width: "100%" }}
title={
innerData.supplement > "0" ? (
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
paddingHorizontal: 5,
}}
>
<Text style={styles.optionDescription}>{innerData.name}</Text>
<Text style={styles.optionPrice}>+ {innerData.supplement}</Text>
</View>
) : (
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
paddingHorizontal: 5,
}}
>
<Text style={styles.optionDescription}>
{innerData.name}
</Text></View>
)
}
textStyle={{ color: "black" }}
checkedIcon="check-square-o"
uncheckedIcon="square-o"
checked= {stringToBoolean(innerData.checked)}
checkedColor="green"
uncheckedColor="green"
onPress={() => {
stringToBoolean(innerData.checked) == false ? setData({ ...data, innerData.checked: true }) : setData({ ...data, innerData.checked: false });
}}
/>
</View>
</View>
)}
/>
</View>
</View>
)}
/>
As you can see some chekboxes come prechecked from the source, some not, my idea was to update the original json object everytime a checkbox gets updated to keep track and thus disable or enable a checkbox according to actual value and the min/max values, but for the life of me i can't seem to get the code to update the object right:
onPress={() => {stringToBoolean(innerData.checked) == false ? setData({ ...data, innerData.checked: true }) : setData({ ...data, innerData.checked: false });}
Any idea how to solve that? and is my idea sound for the whole process of limiting checkboxes?
I started learning react-native and javascript late November and i'm having a blast, big thank you to all the community here sharing ideas and solutions
Please try using a key prop in the checkbox component
Thank you "Great" for your answer, i have meanwhile figured out the answer, i'll share it here for others:
the solution is as follow:
onPress={() => {stringToBoolean(innerData.checked) == false
? Number(item.actual) < item.max
? ((innerData.checked = "true"),
(item.actual = Number(item.actual) + 1))
: showToast("max options reached!")
: (innerData.checked = "false",
item.actual = Number(item.actual) - 1);
}}
Cheers folks.
I am tasked right now with making a screen that gives options in a grid of two columns with multiple cards as the items of a list. (You can see here)
I was trying to create a row flexbox, but it ended up simply continuing horizontally forever.
I'd like to know what would be a good way to get this effect os two columns expanding downwards.
You should use FlatList and set numColumns prop to "2" to show FlatList as grid
Here is complete code sample
import React from "react";
import { SafeAreaView, FlatList, Text, View, Image } from "react-native";
const DATA = [
{
id: "1",
title: "RUSTY DRIVE",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "2",
title: "SABOR MORENO",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "3",
title: "0 MESTRE PUB",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "4",
title: "GRILL 54 CHEF",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "5",
title: "RUSTY DRIVE",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "6",
title: "SABOR MORENO",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "7",
title: "0 MESTRE PUB",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "8",
title: "GRILL 54 CHEF",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
}
];
export default class App extends React.Component {
_renderItem = ({ item }) => (
<View style={{ flex: 1, marginHorizontal: 20, marginBottom: 20 }}>
<Image
style={{ width: "100%", height: 140 }}
source={{ uri: item.image }}
/>
<Text style={{ textAlign: "center", marginTop: 8 }}>{item.title}</Text>
</View>
);
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<FlatList
data={DATA}
renderItem={this._renderItem}
keyExtractor={item => item.id}
numColumns={2}
style={{ flex: 1 }}
contentContainerStyle={{ paddingVertical: 20 }}
/>
</SafeAreaView>
);
}
}
App Preview
You can achieve this by simply doing something like:
<View style={{flex:1, flexDirection:"row", maxHeight:100}}>
<View style={{flex : 1, backgroundColor:"red"}}/>
<View style={{flex : 1, backgroundColor:"yellow"}}/>
</View>
Then adding new views will let you achieve such a layout, then it's up to you deciding what and how many you want to render
I am using Picker and DeckSwiper from NativeBase, when I select a different topic from the Picker menu, it updates the state that is read by dataSource on the DeckSwiper component, which should re render to show the new content. It currently only re renders if the first card is swiped. How can I get it re render as soon as the state has changed? Here is a GIF to show how it's currently working.
Here is the code
const Item = Picker.Item;
const topics = [
{ label: "topic 1", value: "1" },
{ label: "topic 2", value: "2" },
{ label: "topic 3", value: "3" }
];
const cards = [
{ text: "Card A", topicId: "1", name: "One" },
{ text: "Card B", topicId: "2", name: "Two" },
{ text: "Card C", topicId: "3", name: "Three" },
{ text: "Card D", topicId: "1", name: "Four" },
{ text: "Card E", topicId: "2", name: "Five" },
{ text: "Card F", topicId: "3", name: "Six" }
];
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: "1",
topics: topics,
cards: cards
};
}
onValueChange(value: string) {
this.setState({
selected: value,
cards: cards.filter(item => item.topicId === value)
});
}
render() {
return (
<Container>
<Header />
<Content>
<Form>
<Picker
iosHeader="Select one"
mode="dropdown"
selectedValue={this.state.selected}
onValueChange={this.onValueChange.bind(this)}
>
{this.state.topics.map((topic, i) => {
return <Item label={topic.label} value={topic.value} key={i} />;
})}
</Picker>
</Form>
<View>
<DeckSwiper
ref={c => (this._deckSwiper = c)}
dataSource={this.state.cards}
renderItem={item => (
<Card style={{ elevation: 3 }}>
<CardItem>
<Left>
<Body>
<Text>{item.text}</Text>
<Text>Topic{item.topicId}</Text>
</Body>
</Left>
</CardItem>
<CardItem cardBody>
<Image
style={{ height: 300, flex: 1 }}
source={{
uri:
"http://www.pixedelic.com/themes/geode/demo/wp-content/uploads/sites/4/2014/04/placeholder4.png"
}}
/>
</CardItem>
</Card>
)}
/>
</View>
</Content>
<View style={{ flexDirection: "row", flex: 1, position: "absolute", bottom: 50, left: 0, right: 0, justifyContent: 'space-between', padding: 15 }}>
<Button iconLeft onPress={() => this._deckSwiper._root.swipeLeft()}>
<Text>Swipe Left</Text>
</Button>
<Button iconRight onPress={() => this._deckSwiper._root.swipeRight()}>
<Text>Swipe Right</Text>
</Button>
</View>
</Container>
);
}
}