Fetch data from firebase realtime database, React Native (expo) - reactjs

I have that code, I need to fetch data instead of the static array here.
Note: have connected to firebase realtime database and all that stuff, I just need to fetch data and map them, I will need to render them in a list.
const rec = [
{
name: 'Brothers Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
address: 'Address St. Random Number',
link: 'Home'
},
{
name: 'Example Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
address: 'Address St. Random Number 23',
link: 'About'
},
{
name: 'Example Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
address: 'Address St. Random Number 23',
link: 'About'
},
{
name: 'Example Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
address: 'Address St. Random Number 23',
link: 'About'
},
]
const discover = [
{
name: 'Discover Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
address: 'Address St. Random Number',
link: 'Home'
},
{
name: 'Example Discover Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
address: 'Address St. Random Number 23',
link: 'About'
},
{
name: 'Discover Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
address: 'Address St. Random Number',
link: 'Home'
},
{
name: 'Example Discover Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
address: 'Address St. Random Number 23',
link: 'About'
},
{
name: 'Discover Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
address: 'Address St. Random Number',
link: 'Home'
},
{
name: 'Example Discover Restaurant',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
address: 'Address St. Random Number 23',
link: 'About'
},
]
export default class RestaurantScreen extends Component {
static navigationOptions = {
title: 'Restaurants',
headerStyle: {
backgroundColor: '#c4463d',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
render() {
return (
<View style={styles.container}>
<Text style={{ fontSize: 24, fontWeight: '700', color: '#c4463d' }}>Recommendations</Text>
<ScrollView
style={styles.categories}>
<View>
{
rec.map((l, i) => (
<ListItem
key={i}
leftAvatar={{ source: { uri: l.avatar_url } }}
title={l.name}
address={l.subtitle}
onPress={() => this.props.navigation.navigate(`${l.link}`)}
bottomDivider
/>
))
}
</View>
</ScrollView>
<View style={styles.recommendations}>
<Text style={{ fontSize: 24, fontWeight: '700', color: '#c4463d' }}>Discover</Text>
<ScrollView>
{
discover.map((l, i) => (
<ListItem
key={i}
leftAvatar={{ source: { uri: l.avatar_url } }}
title={l.name}
address={l.subtitle}
bottomDivider
/>
))
}
</ScrollView>
</View>
</View>
)
}
}
official documentation from expo didn't help a lot to be honest ^^ and I can't get this thing posted because I have a lot of code in here? -.-

Basically if everything is set up, you just need to put listener at lifecycle method (componentDidMount) and set the data inside state.
for more info, you can check firebase js sdk
https://firebase.google.com/docs/web/setup
export default class RestaurantScreen extends Component {
state = {
rec: [],
discover: []
}
static navigationOptions = {
title: 'Restaurants',
headerStyle: {
backgroundColor: '#c4463d',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
componentDidMount() {
firebase.database().ref('places').on('value', (snapshot) => {
const rec = snapshot.val();
this.setState({ rec, discover: rec })
});
}
render() {
const { rec, discover } = this.state;
return (
<View style={styles.container}>
<Text style={{ fontSize: 24, fontWeight: '700', color: '#c4463d' }}>Recommendations</Text>
<ScrollView
style={styles.categories}>
<View>
{
rec.map((l, i) => (
<ListItem
key={i}
leftAvatar={{ source: { uri: l.avatar_url } }}
title={l.name}
address={l.subtitle}
onPress={() => this.props.navigation.navigate(`${l.link}`)}
bottomDivider
/>
))
}
</View>
</ScrollView>
<View style={styles.recommendations}>
<Text style={{ fontSize: 24, fontWeight: '700', color: '#c4463d' }}>Discover</Text>
<ScrollView>
{
discover.map((l, i) => (
<ListItem
key={i}
leftAvatar={{ source: { uri: l.avatar_url } }}
title={l.name}
address={l.subtitle}
bottomDivider
/>
))
}
</ScrollView>
</View>
</View>
)
}
}

Related

JSX element doesn't render inside a loop

I have an array of stock data for my shopping store which I would like to render in the screen with the help of a for loop. But only the first item in the array is being rendered, while the array have 9 items.
I also have tried putting the render function outside the functional component, still the same issue.
Plz help me to identify the problem. Thanks.
code
const Home = () => {
const [isSneakersActive, setIsSneakersActive] = React.useState(false);
const [isWatchActive, setIsWatchActive] = React.useState(false);
const [isBackpackActive, setIsBackpackActive] = React.useState(false);
const screenWidth = Dimensions.get('window').width;
const renderProducts = () => {
for (let i = 0; i < Products.length; i++) {
const element = Products[i];
return (
<ProductCard>
<ProductHeader>
{element.discount === 'none' ? (
<DiscountLabel style={{backgroundColor: '#fff'}} />
) : (
<DiscountLabel>
<Text size={13} weight="bold">
{element.discount}
</Text>
</DiscountLabel>
)}
{element.favourite === 'yes' ? (
<Ionicons name="heart-circle" color="#F75058" size={20} />
) : (
<AntDesign name="heart" color="#B6B8C7" size={15} />
)}
</ProductHeader>
<ProductPicture>
<View style={ProductPictureStyles.border}>
<View style={ProductPictureStyles.circle}>
<Image
source={element.imageSrc}
style={[
ProductPictureStyles.image,
{
height: (screenWidth / 1731) * 433,
},
]}
/>
</View>
</View>
</ProductPicture>
<ProductName>
<Text color="#3D44AA" size={(screenWidth / 380) * 18} weight="bold">
{element.name}
</Text>
</ProductName>
<ProductPrice>
<Text color="#3D44AA" size={(screenWidth / 380) * 18} weight="bold">
{element.price}
</Text>
</ProductPrice>
<ProductRating>
<AntDesign name="star" color="#fdd344" size={18} />
<AntDesign name="star" color="#fdd344" size={18} />
<AntDesign name="star" color="#fdd344" size={18} />
<AntDesign name="star" color="#fdd344" size={18} />
<AntDesign name="staro" color="#f0e8c9" size={18} />
</ProductRating>
</ProductCard>
);
}
};
return (
<View style={{flex: 1}}>
<Section5 style={{paddingHorizontal: 0}}>
<ScrollView showsVerticalScrollIndicator={false}>
{isSneakersActive ? (
<Section5 style={{paddingHorizontal: 0}}></Section5>
) : isWatchActive ? (
<Section5 style={{paddingHorizontal: 0}}></Section5>
) : isBackpackActive ? (
<Section5 style={{paddingHorizontal: 0}}></Section5>
) : (
<Section5 style={{paddingHorizontal: 0}}>
{renderProducts()}
</Section5>
)}
</ScrollView>
</Section5>
</View>
);
};
export default Home;
stock data
export const Products = [
{
id: 1,
category: 'shoe',
name: 'Air Max Motion',
imageSrc: require('../images/sneekers.png'),
price: '$ 250',
rating: 5,
discount: '8%',
favourite: 'yes',
},
{
id: 2,
category: 'backpack',
name: 'Hiking Starlet',
imageSrc: require('../images/backpack.png'),
price: '$ 350',
rating: 5,
discount: '5%',
favourite: 'yes',
},
{
id: 3,
category: 'backpack',
name: 'Hand Bag',
imageSrc: require('../images/backpack02.png'),
price: '$ 80',
rating: 3.5,
discount: '8%',
favourite: 'no',
},
{
id: 4,
category: 'shoe',
name: 'Nike Air Max',
imageSrc: require('../images/sneekers02.png'),
price: '$ 240',
rating: 4,
discount: 'none',
favourite: 'no',
},
{
id: 5,
category: 'watch',
name: 'Royal Rolex',
imageSrc: require('../images/watch.png'),
price: '$ 50',
rating: 5,
discount: 'none',
favourite: 'no',
},
{
id: 6,
category: 'shoe',
name: 'Hiker Max',
imageSrc: require('../images/sneekers03.png'),
price: '$ 180',
rating: 4.5,
discount: 'none',
favourite: 'no',
},
{
id: 7,
category: 'backpack',
name: 'School Bag',
imageSrc: require('../images/backpack01.png'),
price: '$ 120',
rating: 3.5,
discount: '10%',
favourite: 'no',
},
{
id: 8,
category: 'watch',
name: 'Silver Liner',
imageSrc: require('../images/watch01.png'),
price: '$ 35',
rating: 4.5,
discount: '22%',
favourite: 'yes',
},
{
id: 9,
category: 'shoe',
name: 'Leather Sneaker',
imageSrc: require('../images/sneekers01.png'),
price: '$ 200',
rating: 4,
discount: 'none',
favourite: 'no',
},
];
The problem is that your are looping the array but returning just the first element.
the correct way to do it is via map
const renderProducts = () => {
for (let i = 0; i < Products.length; i++) {
const element = Products[i];
return ( //return just the first
<ProductCard>
...
</ProductCard>
);
}
};
const renderProducts = () => products.map((element, i) => {
return (
<ProductCard key={i}>
...
</ProductCard>
);
};

React Ant deisgn 4 Table search input cursor going to center

Im using my react project for ant design 4 table, when I search the table data , input cursor going to center and data not searching any solution for this, please look ta my following link and just copy paste address then search you can see the conflict.
stakblitz
code here
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Joe Black',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Jim Green',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
];
class App extends React.Component {
state = {
searchText: '',
searchedColumn: '',
};
getColumnSearchProps = dataIndex => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
ref={node => {
this.searchInput = node;
}}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
style={{ width: 188, marginBottom: 8, display: 'block' }}
/>
<Space>
<Button
type="primary"
onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => this.handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: '',
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => this.searchInput.select(), 100);
}
},
render: text =>
this.state.searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[this.state.searchText]}
autoEscape
textToHighlight={text ? text.toString() : ''}
/>
) : (
text
),
});
handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
};
handleReset = clearFilters => {
clearFilters();
this.setState({ searchText: '' });
};
render() {
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: '30%',
...this.getColumnSearchProps('name'),
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: '20%',
...this.getColumnSearchProps('age'),
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
...this.getColumnSearchProps('address'),
},
];
return <Table columns={columns} dataSource={data} />;
}
}

How to render items in react native FlatList with 2 columns when some of them must be full width

I want to render product list in React Native with 2 columns by default, but if any item is a special product, then make it full width.
const data = [
{id: '1', name: 'Item1', price: 25, special_product: false},
{id: '2', name: 'Item2', price: 15, special_product: false},
{id: '3', name: 'Item3', price: 11, special_product: true},
{id: '4', name: 'Item4', price: 22, special_product: false},
{id: '5', name: 'Item5', price: 32, special_product: false},
{id: '6', name: 'Item6', price: 22, special_product: false},
{id: '7', name: 'Item7', price: 22, special_product: false},
]
And I want to get FlatList structure like this:
[Item 1][Item2]
[Special Item3]
[Item4] [Item5]
[Item6] [Item7]
My code is really simple now:
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
contentContainerStyle={{ flexGrow: 1 }}
horizontal={false}
data={data}
keyExtractor={({ id }) => id}
onRefresh={this.onListRefresh}
refreshing={refreshing}
renderItem={this.renderItems}
ListHeaderComponent={this.renderHeader}
ListEmptyComponent={this.renderEmptyList.bind(this, data, use)}
/>
My item container styles looks like this:
const Styles = StyleSheet.create({
container: {
flex: 0.5,
margin: Layout.Margin.Narrow,
shadowColor: ShadowColor.Standard,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 4,
elevation: 5,
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5,
},
...
});
Item that is rendered by renderItem function:
// Item
...
return (
<TouchableWithoutFeedback
onPress={() => console.log('user clicked on the item')}>
<View style={{
...itemStyle.container
}}
<StyledText
type={"small"}
numberOfLines={1}
allowFontScaling={false}
style={itemStyle.centerText}>
{name}
</StyledText>
</View>
</TouchableWithoutFeedback>
How can I do this? I'm using React Native v0.60.5
You can use the number of columns prop and provide a width of 100% this will give the output you need.
This is a working sample you can apply it your item styles in anyway you need.
Flatlist code
<FlatList
numColumns={2}
data={data}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.name}
selected={item.special_product}
/>
)}
keyExtractor={(item) => item.id}
/>
Render item function
function Item({ id, title, selected }) {
return (
<TouchableOpacity
onPress={() => {}}
style={[
selected ? { width: '100%' } : { width: '50%' },
{ backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' },
]}>
<Text style={{}}>{title}</Text>
</TouchableOpacity>
);
}
As you can see I've set the width conditionally based the selected flag.

Cannot read property 0 of undefined

I have tried desperately to resolve this issue but still befuddled. Getting "Cannot read property 0 of undefined" error trying to pass array gallery[] which has photos as the first (0) index.
I have verified that the array gallery does exist and in the correct format when I console.log it. However, I am not sure why 2 console statements are returned with the first one being undefined and the second one being correct.
Please see code snippets and screen capture below for details. I will appreciate your help as I am completely lost. This is the only aspect delaying completing my app dev. Thanks
<Text style={styles.sectionHeader}> Photo Galery</Text>
<View >
{console.log(gallery)}
{
<TouchableOpacity >
<Image
source={gallery[0].photos}
style={styles.navImageStyle}
/>
</TouchableOpacity>
}
Here's the screenshot with correct gallery object defined. I have tried all kinds of ways to reference it in my image tag (even using source={{uri: gallery[0].photos}} but no luck.
When I revise the image tag with source={gallery}, no images displayed at all even though I know that syntax is incomplete. See image below.
--- More detail below per request -----
The gallery array is from a local data array (placesData) that is imported by code below. The code then imports gallery as a prop in a modal window (SiteDetails) upon button press
import React, { Component } from 'react';
import { View, FlatList } from 'react-native';
import { ListItem, } from 'native-base';
import { placesData } from '../../data/placesData';
import Places from '../../data/Places';
import SiteDetails from '../SiteDetails';
export default class NavPlaces extends Component {
constructor(props) {
super(props);
this.state = {
setModalVisible: false,
modalArticleData: {},
error: null
};
}
_handleItemDataOnPress = articleData => {
this.setState({
setModalVisible: true,
modalArticleData: articleData
});
};
_handleModalClose = () => {
this.setState({
setModalVisible: false,
modalArticleData: {}
});
};
render() {
return (
<View>
<FlatList
data={placesData}
renderItem={({ item }) => (
<ListItem style={{ marginLeft: 5,}}>
<Places onPress={this._handleItemDataOnPress} data={item} />
</ListItem>
)}
horizontal={true}
keyExtractor={item => item.id}
/>
<SiteDetails
showModal={this.state.setModalVisible}
articleData={this.state.modalArticleData}
onClose={this._handleModalClose}
/>
</View>
);
}
}
SiteDetails
import React, { Component } from "react";
import Icon from "react-native-vector-icons/FontAwesome";
import {
FlatList,
Dimensions,
Modal,
ScrollView,
Share,
TouchableOpacity, Image, Text, View,
} from "react-native";
import {
Grid, Row, Col,
Header,
ListItem,
Content,
Container,
Body,
Left,
Right,
Title,
} from "native-base";
// import PlacePhoto from '../data/PlacePhoto';
// import NavGallery from "./Tabs/NavGallery";
// import {placesData} from '../data/placesData'
const webViewHeight = Dimensions.get("window").height - 56;
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
export default class SiteDetails extends Component {
constructor(props) {
super(props);
this.data = props.data;
}
_handleClose = () => {
return this.props.onClose();
};
_handleShare = (clickedLink, clickedTitle) => {
// const { link,title } = this.props.data;
message = `${clickedTitle}\n\nRead more #\n${clickedLink.toString()}\n\nshared via MSU mobile`;
return Share.share(
{ clickedTitle, message, url: message },
{ dialogTitle: `Share ${clickedTitle}` }
);
};
render() {
const { showModal, articleData } = this.props;
const { image, title, subTitle, description,location, phone, credit, gallery } = articleData;
// if (image !== undefined) {
return (
<Modal
onRequestClose={this._handleClose}
visible={showModal}
transparent
animationType="slide"
>
<Container
style={{ margin: 0, marginBottom: 0, backgroundColor: "#ffffff" }}
>
<Content contentContainerStyle={{ height: webViewHeight }}>
<Header
style={{ backgroundColor: "#1b4383" }}
iosBarStyle="light-content"
>
<Left>
<TouchableOpacity onPress={() => this._handleClose()}>
<Icon
name="close"
style={{ fontSize: 25, color: "#f47937", paddingHorizontal: 10, }}
/>
</TouchableOpacity>
</Left>
<Body>
<Title
children={title}
style={{ color: "#ffffff" }}
/>
</Body>
<Right>
<TouchableOpacity
// onPress={() =>
// this._handleShare(articleData.link, articleData.title)
// }
>
<Icon
name="share-alt"
style={{ fontSize: 30, color: "#f47937", paddingHorizontal: 10, }}
/>
</TouchableOpacity>
</Right>
</Header>
<ScrollView>
<Image
source={image}
style={styles.drawerCover}
/>
<View style={{backgroundColor: 'black', }}>
<Text style={styles.titleText}>{title}</Text>
<View style={{ height: 16 }}/>
<Text style={styles.subTitleText}>{subTitle}</Text>
<View style={{ height: 16 }}/>
<Grid>
<Row>
<Col style={{ flexDirection: 'row'}}>
<Icon
name='map-o'
style={styles.iconStyle}
/>
<Text style={styles.subText}>location:</Text>
</Col>
<Col>
<Text style={styles.subText}>{location}</Text>
</Col>
</Row>
<View style={{ height: 16 }}/>
<Row>
<Col style={{ flexDirection: 'row'}}>
<Icon
name='phone'
style={styles.iconStyle}
/>
<Text style={styles.subText}>tel:</Text>
</Col>
<Col>
<Text style={styles.subText}>{phone}</Text>
</Col>
</Row>
<View style={{ height: 16 }}/>
<Row>
<Col style={{ flexDirection: 'row'}}>
<Icon
name='globe'
style={styles.iconStyle}
/>
<Text style={styles.subText}>Website:</Text>
</Col>
<Col>
<Text style={styles.subText}></Text>
</Col>
</Row>
<View style={{ height: 16 }}/>
<Row>
<Col style={{ flexDirection: 'row'}}>
<Icon
name='pencil'
// name='creative-commons'
style={styles.iconStyle}
/>
<Text style={styles.subText}>Credit:</Text>
</Col>
<View style={{ height: 16 }}/>
<Col>
<Text style={styles.subText}>{credit}</Text>
</Col>
</Row>
</Grid>
</View>
<Text style={styles.sectionHeader}> Photo Galery</Text>
<View >
{console.log(gallery)}
{
<TouchableOpacity >
<Image
source={gallery}
style={styles.navImageStyle}
/>
</TouchableOpacity>
}
<Text style={styles.sectionHeader}> Description </Text>
<Text style={styles.bodyText}> {description} </Text>
</View>
</ScrollView>
</Content>
</Container>
</Modal>
);
// } else {
// return null;
// }
}
}
placesData array:
export const placesData =
[
{
id: 'a',
image: require('../../assets/img/places/museum/slave/slavePic.jpg'),
title: 'Slave Trade Museum',
subTitle: 'One of many rare gems of history and education',
location: 'Badagry, Lagos',
phone: '',
credit: 'The Freeman Institute',
gallery:[
{
key: 'v1',
photos: [
require('../../assets/img/places/museum/slave/abolitionCannon.jpg'),
require('../../assets/img/places/museum/slave/holdingCell.jpg'),
require('../../assets/img/places/museum/slave/slaveMarket.jpg'),
require('../../assets/img/places/museum/slave/slaveNoReturn.jpg'),
require('../../assets/img/places/museum/slave/bibleAtBadagry.jpg'),
require('../../assets/img/places/museum/slave/bridge.jpg'),
]
}
],
description: 'Excerpts from Freeman Institute',
},
{
id: 'b',
image: require('../../assets/img/places/parks/yankari.png'),
title: 'Parks and WildLife',
subTitle: 'Visit to this wildlife park will rejuvenate your mind and spirit',
location: 'Jos, Lagos, Calabar, Abuja, etc',
phone: '',
credit: 'The Freeman Institute',
gallery:[
{
id: 'v2',
photos: [
require('../../assets/img/places/parks/ikogosi.png'),
require('../../assets/img/places/parks/abujaPark.png'),
require('../../assets/img/places/parks/raindeer.png'),
require('../../assets/img/places/parks/kainji.png'),
require('../../assets/img/places/parks/elephant.png'),
require('../../assets/img/places/parks/owuH2OFalls.png'),
]
}
],
description: 'Excerpts from online wiki',
},
{
id: 'c',
image: require('../../assets/img/places/resorts/badagry.png'),
title: 'Resorts and Beaches',
subTitle: 'Simply exquisite vacation sites, peaceful and beautiful beaches. Go on horseback riding or whatever suits you.',
location: 'Lagos, Calabar, Abuja, etc',
phone: '',
credit: 'Online wiki',
gallery:[
{
id: 'v3',
photos: [
require('../../assets/img/places/resorts/funtopiaPark.png'),
require('../../assets/img/places/resorts/barBeach.png'),
require('../../assets/img/places/resorts/obudu.png'),
require('../../assets/img/places/resorts/funtopiaPark.png'),
require('../../assets/img/places/resorts/whisperingPalms.png'),
require('../../assets/img/places/resorts/tinapa.png'),
]
}
],
description: 'Excerpts from online wiki',
},
{
id: 'd',
image: require('../../assets/img/places/museum/museumBeni.png'),
title: 'National Musuems',
subTitle: 'Incredible museums of history and education with variety to enrich the minds.',
location: 'Lagos, Jos, Kaduna, Enugu, Benin, etc',
phone: '',
credit: 'Ministry of Tourism',
gallery:[
{
id: 'v4',
photos: [
require('../../assets/img/places/museum/museumLagos.jpg'),
require('../../assets/img/places/museum/museumWar.jpg'),
require('../../assets/img/places/museum/museumKaduna.jpg'),
require('../../assets/img/places/museum/museumOwo.jpg'),
require('../../assets/img/places/museum/museumColonia.jpg'),
require('../../assets/img/places/museum/museumOwo.jpg'),
]
}
],
description: 'Excerpts from online wiki',
},
]
// export const placesData =
// [
// {
// id: 'a',
// image: require('../../assets/img/places/museum/slave/slavePic.jpg'),
// title: 'Slave Trade Museum',
// subTitle: 'One of many rare gems of history and education',
// location: 'Badagry, Lagos',
// phone: '',
// credit: 'The Freeman Institute',
// photos:{
// key: 'a1',
// pic1: require('../../assets/img/places/museum/slave/abolitionCannon.jpg'),
// pic2: require('../../assets/img/places/museum/slave/holdingCell.jpg'),
// pic3: require('../../assets/img/places/museum/slave/slaveMarket.jpg'),
// pic4: require('../../assets/img/places/museum/slave/slaveNoReturn.jpg'),
// pic5: require('../../assets/img/places/museum/slave/bibleAtBadagry.jpg'),
// pic6: require('../../assets/img/places/museum/slave/bridge.jpg'),
// },
// description: 'Excerpts from Freeman Institute',
// },
// {
// id: 'b',
// image: require('../../assets/img/places/parks/yankari.png'),
// title: 'Parks and WildLife',
// subTitle: 'Visit to this wildlife park will rejuvenate your mind and spirit',
// location: 'Jos, Lagos, Calabar, Abuja, etc',
// phone: '',
// credit: 'The Freeman Institute',
// photos:{
// key: 'b1',
// pic1: require('../../assets/img/places/parks/ikogosi.png'),
// pic2: require('../../assets/img/places/parks/abujaPark.png'),
// pic3: require('../../assets/img/places/parks/raindeer.png'),
// pic4: require('../../assets/img/places/parks/kainji.png'),
// pic5: require('../../assets/img/places/parks/elephant.png'),
// pic6: require('../../assets/img/places/parks/owuH2OFalls.png'),
// },
// description: 'Excerpts from online wiki',
// },
// {
// id: 'c',
// image: require('../../assets/img/places/resorts/badagry.png'),
// title: 'Resorts and Beaches',
// subTitle: 'Simply exquisite vacation sites, peaceful and beautiful beaches. Go on horseback riding or whatever suits you.',
// location: 'Lagos, Calabar, Abuja, etc',
// phone: '',
// credit: 'Online wiki',
// photos:{
// key: 'c1',
// pic1: require('../../assets/img/places/resorts/funtopiaPark.png'),
// pic2: require('../../assets/img/places/resorts/barBeach.png'),
// pic3: require('../../assets/img/places/resorts/obudu.png'),
// pic4: require('../../assets/img/places/resorts/funtopiaPark.png'),
// pic5: require('../../assets/img/places/resorts/whisperingPalms.png'),
// pic6: require('../../assets/img/places/resorts/tinapa.png'),
// },
// description: 'Excerpts from online wiki',
// },
// {
// id: 'd',
// image: require('../../assets/img/places/museum/museumBeni.png'),
// title: 'National Musuems',
// subTitle: 'Incredible museums of history and education with variety to enrich the minds.',
// location: 'Lagos, Jos, Kaduna, Enugu, Benin, etc',
// phone: '',
// credit: 'Ministry of ?',
// photos:{
// key: 'd1',
// pic1: require('../../assets/img/places/museum/museumLagos.jpg'),
// pic2: require('../../assets/img/places/museum/museumWar.jpg'),
// pic3: require('../../assets/img/places/museum/museumKaduna.jpg'),
// pic4: require('../../assets/img/places/museum/museumOwo.jpg'),
// pic5: require('../../assets/img/places/museum/museumColonia.jpg'),
// pic6: require('../../assets/img/places/museum/museumOwo.jpg'),
// },
// description: 'Excerpts from online wiki',
// },
// ]

What Approach should I use to make each cards swipe either right/left as tinder?React Native?

What approach should I use to make each cards swipe either right/left as tinder?
My cards are in listview.Once I swipe any card right or left it should vanish off and the next stacked card should come up at that place? In React Native.
The imports :
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,Image,ListView,TouchableOpacity
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import { TabNavigator, StackNavigator } from 'react-navigation';
import { Col, Row, Grid } from 'react-native-easy-grid';
import { Container, Header, Content, Card, CardItem, Thumbnail, Button, Left, Body, Right } from 'native-base';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
export default class Scenes extends Component{
static navigationOptions = {
tabBarLabel: 'Scenes',
tabBarIcon: ({ tintColor }) => (
<Image
source={require('./video.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
Function displaying users:
displayImages(users){
var {navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Content style={{paddingTop: 20, borderWidth: 0, shadowOpacity: 0,
shadowOffset: {
height: 0,
width:0
},
shadowRadius: 0,}}>
<Card style={{borderWidth: 0}} transparent>
<CardItem style={{height: 48,borderWidth:0,}}>
<Left>
<Thumbnail source={{uri: users.avatar_url}} style={{height: 40, width: 40}} />
<Body>
<Text style={styles.uploaderName}>{users.name}</Text>
</Body>
</Left>
<Right>
<Image
source={require('./follow.png')}
style={{height: 23, width: 42}}
/>
</Right>
</CardItem>
<CardItem cardBody>
<Image source={{uri: users.image}} style={{height: 322, width: null, flex: 1}}/>
</CardItem>
<CardItem style={{height: 48,borderWidth:0,}}>
<Left>
<TouchableOpacity onPress = { () => navigate ("profile", {}) }>
<Icon style={{color:'#f00039'}} name={'md-heart'} size={20}/>
</TouchableOpacity>
<Text style={{marginLeft:2}}>46</Text>
<Image
source={require('./sharePost.png')}
style={{height: 20, width: 25, marginLeft: 15}}
/>
</Left>
<Body>
<Button transparent>
</Button>
</Body>
<Right>
</Right>
</CardItem>
</Card>
</Content>
</View>
);
}
The render method:
render() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var users = [
{
name: 'Amy Farha',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
image: 'https://i.pinimg.com/564x/1c/f3/05/1cf305362aed02ad559f989687b1460e.jpg',
},
{
name: 'Chris Jackson',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
image: 'https://i.pinimg.com/236x/a8/37/8e/a8378eeb01ec788a0068ea6b1b759091.jpg',
},
{
name: 'Amanda Martin',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg',
image: 'https://i.pinimg.com/564x/8a/db/a7/8adba7207bdc82668bf06acc2734537e.jpg',
},
{
name: 'Amy Farha',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
image: 'https://i.pinimg.com/564x/8a/db/a7/8adba7207bdc82668bf06acc2734537e.jpg',
},
{
name: 'Chris Jackson',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
image: 'https://i.pinimg.com/564x/66/f0/2f/66f02f37eb54ff7f79f4c831212b231f.jpg',
},
{
name: 'Amanda Martin',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg',
image: 'https://i.pinimg.com/564x/58/0c/78/580c789ded6ceeafdf71b792b0d57ac6.jpg',
},
{
name: 'Amy Farha',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
image: 'https://i.pinimg.com/564x/a5/4d/4d/a54d4d37522a76a67002fa25b8e51515.jpg',
},
{
name: 'Chris Jackson',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
image: 'https://i.pinimg.com/564x/47/6b/5c/476b5c4c9725ff3cd4bb3e5f61e4d6c3.jpg',
},
{
name: 'Amanda Martin',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg',
image: 'https://i.pinimg.com/564x/ad/4b/06/ad4b06523eefacc30d09d41a9992029f.jpg',
},
{
name: 'Christy Thomas',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/kfriedson/128.jpg',
image: 'https://i.pinimg.com/564x/a5/4d/4d/a54d4d37522a76a67002fa25b8e51515.jpg',
},
{
name: 'Melissa Jones',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/nuraika/128.jpg',
image: 'https://i.pinimg.com/564x/82/ac/2e/82ac2e1c86692090173666496b9ce1cf.jpg',
},
{
name: 'Amanda Martin',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg',
image: 'https://i.pinimg.com/564x/8a/db/a7/8adba7207bdc82668bf06acc2734537e.jpg',
},
{
name: 'Christy Thomas',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/kfriedson/128.jpg',
image: 'https://i.pinimg.com/564x/a5/4d/4d/a54d4d37522a76a67002fa25b8e51515.jpg',
},
{
name: 'Melissa Jones',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/nuraika/128.jpg',
image: 'https://i.pinimg.com/564x/ae/b6/ac/aeb6ac2f05644f1464c298bf979630e9.jpg',
},
{
name: 'Christy Thomas',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/kfriedson/128.jpg',
image: 'https://i.pinimg.com/564x/57/ac/3e/57ac3e724c61f9b9803d520574e42a1e.jpg',
},
{
name: 'Melissa Jones',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/nuraika/128.jpg',
image: 'https://i.pinimg.com/564x/66/f0/2f/66f02f37eb54ff7f79f4c831212b231f.jpg',
},
];
The view component:
var cloneUsers = ds.cloneWithRows(users);
return (
<View style={{flex: 1}}>
<ListView
style={styles.listView}
dataSource={cloneUsers}
renderRow={this.displayImages.bind(this)}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
/>
</View>
);
}
}
This is the styling:
const styles = StyleSheet.create({
icon: {
width: 26,
height: 26,
},
container: {
flex: 1,
backgroundColor: '#F5F5F5',
paddingHorizontal : 25,
},
uploaderName:{
fontSize: 16,
color: '#36292a'
}
});
In React I used HammerJS to do this.
ReactNative has a built in library called PanResponder. There are examples out there.
To make a swipe deck like Tinder in react-native you can use a library called react-native-swipe-decker. It's a pretty straightforward library, there's a stack of cards and there are actions like onSwipedLeft onSwipedRight onSwipedAll. You can define functions for each of them if you wish to customize. By default all the card contents need to be in an array and no matter which direction you swipe you move to the next card. You can also add infinite loop to it. You can have a look at the GitHub repository for the project and check out their example.

Resources