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
I am creating my first professional react native app for a new start up, I like to do so.
This is based om a Product delarship.
Since I am not able to Pass the checked products to the Cart Page. Please Help me to do future.
I just created it in expo for react-native
Please Help me
Please Help I am stuck here.
import React from "react";
import styled from "styled-components";
import { Dimensions } from "react-native";
import { StatusBar } from "expo-status-bar";
import MedCard from "../components/MidCard";
import ProductName from "../components/Prices";
import Price from "../components/Prices";
import { LinearGradient } from "expo-linear-gradient";
import {
StyleSheet,
Button,
Text,
View,
TouchableOpacity,
ScrollView,
Image,
ActivityIndicator,
TextInput,
Alert,
} from "react-native";
import {
MaterialIcons,
AntDesign,
Ionicons,
MaterialCommunityIcons,
} from "#expo/vector-icons";
import { color } from "react-native-reanimated";
class Pulsars extends React.Component {
constructor(props) {
super(props);
this.state = {
selectAll: false,
cartItemsIsLoading: false,
cartItems: [
/* Sample data from walmart */
{
itemId: "1",
name: "Orid Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81f17QBywiL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "2",
name: "Orid Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81f17QBywiL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "3",
name: "Toor Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81ieFDa5gHL._SY550_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "4",
name: "Toor Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/81ieFDa5gHL._SY550_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "5",
name: "Gram Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/udhayam-gram-dal-228x228-1.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "6",
name: "Gram Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/05/udhayam-gram-dal-228x228-1.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "7",
name: "Moong Dhall",
quantity: "1kg",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/12/819D8piBVKL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
{
itemId: "8",
name: "Moong Dhall",
quantity: "500g",
status: "Currently Not Available",
thumbnailImage:
"https://annaistores.com/as_content/uploads/2020/12/819D8piBVKL._SL1500_.jpg",
qty: 5,
salePrice: "123",
checked: 0,
},
],
};
}
selectHandler = (index, value) => {
const newItems = [...this.state.cartItems]; // clone the array
newItems[index]["checked"] = value == 1 ? 0 : 1; // set the new value
this.setState({ cartItems: newItems }); // set new state
};
selectHandlerAll = (value) => {
const newItems = [...this.state.cartItems]; // clone the array
newItems.map((item, index) => {
newItems[index]["checked"] = value == true ? 0 : 1; // set the new value
});
this.setState({
cartItems: newItems,
selectAll: value == true ? false : true,
}); // set new state
};
deleteHandler = (index) => {
Alert.alert(
"Are you sure you want to delete this item from your cart?",
"",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel",
},
{
text: "Delete",
onPress: () => {
let updatedCart = this.state.cartItems; /* Clone it first */
updatedCart.splice(
index,
1
); /* Remove item from the cloned cart state */
this.setState(updatedCart); /* Update the state */
},
},
],
{ cancelable: false }
);
};
quantityHandler = (action, index) => {
const newItems = [...this.state.cartItems]; // clone the array
let currentQty = newItems[index]["qty"];
if (action == "more") {
newItems[index]["qty"] = currentQty + 5;
} else if (action == "less") {
newItems[index]["qty"] = currentQty > 5 ? currentQty - 5 : 5;
}
this.setState({ cartItems: newItems }); // set new state
};
subtotalPrice = () => {
const { cartItems } = this.state;
if (cartItems) {
return cartItems.reduce(
(sum, item) =>
sum + (item.checked == 1 ? item.qty * item.salePrice : 0),
0
);
}
return 0;
};
render() {
const styles = StyleSheet.create({
centerElement: { justifyContent: "center", alignItems: "center" },
});
const { cartItems, cartItemsIsLoading, selectAll } = this.state;
return (
<View style={{ flex: 1, backgroundColor: "#f6f6f6" }}>
<View
style={{
flexDirection: "row",
backgroundColor: "#fff",
marginBottom: 10,
}}
>
<View style={[styles.centerElement, { width: 50, height: 50 }]}>
<Ionicons name="ios-cart" size={25} color="#000" />
</View>
<View style={[styles.centerElement, { height: 50 }]}>
<Text style={{ fontSize: 18, color: "#000" }}>Shopping Cart</Text>
</View>
</View>
{cartItemsIsLoading ? (
<View style={[styles.centerElement, { height: 300 }]}>
<ActivityIndicator size="large" color="#ef5739" />
</View>
) : (
<ScrollView>
{cartItems &&
cartItems.map((item, i) => (
<View
key={i}
style={{
flexDirection: "row",
backgroundColor: "#fff",
marginBottom: 2,
height: 120,
}}
>
<View style={[styles.centerElement, { width: 60 }]}>
<TouchableOpacity
style={[styles.centerElement, { width: 32, height: 32 }]}
onPress={() => this.selectHandler(i, item.checked)}
>
<Ionicons
name={
item.checked == 1
? "ios-checkmark-circle"
: "ios-checkmark-circle-outline"
}
size={25}
color={item.checked == 1 ? "#0faf9a" : "#aaaaaa"}
/>
</TouchableOpacity>
</View>
<View
style={{
flexDirection: "row",
flexGrow: 1,
flexShrink: 1,
alignSelf: "center",
}}
>
<TouchableOpacity
onPress={() => {
/*this.props.navigation.navigate('ProductDetails', {productDetails: item})*/
}}
style={{ paddingRight: 10 }}
>
<Image
source={{ uri: item.thumbnailImage }}
style={[
styles.centerElement,
{ height: 60, width: 60, backgroundColor: "#eeeeee" },
]}
/>
</TouchableOpacity>
<View
style={{
flexGrow: 1,
flexShrink: 1,
alignSelf: "center",
}}
>
<Text numberOfLines={1} style={{ fontSize: 15 }}>
{item.name}
</Text>
<Text numberOfLines={1} style={{ color: "#8f8f8f" }}>
{item.quantity}
</Text>
<Text numberOfLines={1} style={{ color: "#333333" }}>
₹{item.qty * item.salePrice}
</Text>
<Text>{item.status}</Text>
<View style={{ flexDirection: "row" }}>
<TouchableOpacity
onPress={() => this.quantityHandler("less", i)}
style={{ borderWidth: 1, borderColor: "#cccccc" }}
>
<MaterialIcons
name="remove"
size={22}
color="#cccccc"
/>
</TouchableOpacity>
<Text
style={{
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: "#cccccc",
paddingHorizontal: 7,
paddingTop: 3,
color: "#bbbbbb",
fontSize: 13,
}}
>
{item.qty}
</Text>
<TouchableOpacity
onPress={() => this.quantityHandler("more", i)}
style={{ borderWidth: 1, borderColor: "#cccccc" }}
>
<MaterialIcons name="add" size={22} color="#cccccc" />
</TouchableOpacity>
</View>
</View>
</View>
<View style={[styles.centerElement, { width: 60 }]}>
<TouchableOpacity
style={[styles.centerElement, { width: 32, height: 32 }]}
onPress={() => this.deleteHandler(i)}
>
<Ionicons name="md-trash" size={25} color="#ee4d2d" />
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
)}
{!cartItemsIsLoading && (
<View
style={{
backgroundColor: "#fff",
borderTopWidth: 2,
borderColor: "#f6f6f6",
paddingVertical: 5,
}}
>
<View style={{ flexDirection: "row" }}>
<View style={[styles.centerElement, { width: 60 }]}>
<View
style={[styles.centerElement, { width: 32, height: 32 }]}
></View>
</View>
<View
style={{
flexDirection: "row",
flexGrow: 1,
flexShrink: 1,
justifyContent: "space-between",
alignItems: "center",
}}
></View>
</View>
<View style={{ flexDirection: "row" }}>
<View style={[styles.centerElement, { width: 60 }]}>
<TouchableOpacity
style={[styles.centerElement, { width: 32, height: 32 }]}
onPress={() => this.selectHandlerAll(selectAll)}
>
<Ionicons
name={
selectAll == true
? "ios-checkmark-circle"
: "ios-checkmark-circle-outline"
}
size={25}
color={selectAll == true ? "#0faf9a" : "#aaaaaa"}
/>
</TouchableOpacity>
</View>
<View
style={{
flexDirection: "row",
flexGrow: 1,
flexShrink: 1,
justifyContent: "space-between",
alignItems: "center",
}}
>
<Text>Select All</Text>
<View
style={{
flexDirection: "row",
paddingRight: 20,
alignItems: "center",
}}
>
<Text style={{ color: "#8f8f8f" }}>SubTotal: </Text>
<Text>₹{this.subtotalPrice().toFixed(2)}</Text>
</View>
</View>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "flex-end",
height: 32,
paddingRight: 20,
alignItems: "center",
}}
>
<TouchableOpacity
style={[
styles.centerElement,
{
backgroundColor: "#0faf9a",
width: 100,
height: 25,
borderRadius: 5,
},
]}
onPress={() => console.log("test")}
>
<Text style={{ color: "#ffffff" }}>Add to Cart</Text>
</TouchableOpacity>
</View>
</View>
)}
</View>
);
}
}
export default Pulsars;
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 created this list of items and I want to let user select one item and then change style of this item.
this is my approach:
class Gift extends React.Component {
constructor(props){
super(props)
this.titleUpValue = new Animated.Value(0);
this.state = {
isLoading: false,
listGifts: [
{
"id" : "1",
"type" : 'gift' ,
"etat" : 1,
"titreTransaction": "عدد الوحدات",
"contenuTrans": "400",
"dateTrans": "2019-07-31 17:47:31"
},
{
"id" : "2",
"type" : 'ba' ,
"etat" : 1,
"titreTransaction": "عدد الوحدات",
"contenuTrans": "1000",
"dateTrans": "2019-07-31 17:42:57"
},
{
"id" : "3",
"type" : 'ba' ,
"etat" : 1,
"titreTransaction": "عدد الوحدات",
"contenuTrans": "500",
"dateTrans": "2019-07-31 17:31:35"
},
}
],
itemId: null,
btnDisabled: true,
itemindex: null,
}
}
PressedItem = (itemId) => {
this.setState({ itemId: itemId, btnDisabled: false,})
}
renderItem = ({ item }) => {
return (
<TouchableOpacity
onPress={() => { this.setState({ itemindex: item.id, itemId: item.id, btnDisabled: !this.state.btnDisabled, }), console.warn('id > ' + this.state.btnDisabled) }}
style= {[
StylesGift.giftItem,
this.state.itemindex === item.id ? StylesGift.SelectedlistItem : StylesGift.UnselectedlistItem
]}>
<Image source={Images.gift1}
style={StylesGift.imageStyle}
resizeMode={'contain'}
/>
<View style= {StylesGift.footGift}>
<View style= {StylesGift.nameGiftContainer}>
<View style= {StylesGift.valueGiftContainer}>
<Text style= {StylesGift.valueGiftText}>200</Text>
</View>
<Text style= {StylesGift.nameGiftText}>الهدايا</Text>
<Text style= {StylesGift.nameGiftText}>{item.id}</Text>
</View>
</View>
<View style= {StylesGift.headGift}>
<View style= {StylesGift.icGiftContainer}>
<IconFA name="check" size={hp('1.6%')} color= {Colors.white} style={StylesGift.icGift}/>
</View>
</View>
</TouchableOpacity>
)
}
render() {
return (
<View style={Styles.listContainer}>
{
this.state.isLoading ?
<ActivityIndicator size='large' style={Styles.styleAI} color={Colors.mainYellow}/>
:
<FlatList
style={Styles.flatlist}
contentContainerStyle={Styles.flatContent}
data={this.state.listGifts}
keyExtractor={(item) => item.id.toString()}
renderItem={this.renderItem}
numColumns={2}
/>
}
</View>
);
}
}
export default Gift;
I dont use the PressedItem function for test, the consol.warn() in onPress show the last state not the current state.
for exemple when I click on the item with id = "1" it show me id > null when I click on the item with id = "2" then it show me id > 1... and the style deosn't change even with this condition:
this.state.itemindex === item.id ? StylesGift.SelectedlistItem : StylesGift.UnselectedlistItem
this is the 3 main Styles:
giftItem: {
width: wp('42%'),
height: hp('30%'),
alignItems: 'center',
backgroundColor: Colors.white,
borderRadius: wp('2%'),
overflow: 'hidden',
marginVertical: wp('2%'),
marginHorizontal: wp('2%'),
// borderWidth: 1, borderColor: 'blue',
},
UnselectedlistItem: {
elevation: 2,
borderWidth: 1, borderColor: 'red',
},
SelectedlistItem: {
elevation: 8,
borderWidth: 1, borderColor: 'blue',
},
I think my approach is logic and most work but I don't know what's wrong, states: itemindex and itemId doesn't change in setState
It's okey, I just had to add extraData={this.state} as parameter in flatlist for telling the flatlist to re-render
<FlatList
style={Styles.flatlist}
contentContainerStyle={Styles.flatContent}
data={this.state.listGifts}
keyExtractor={(item) => item.id.toString()}
renderItem={this.renderItem}
numColumns={2}
extraData={this.state}
/>
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>
);
}
}