React Native Zomato API reviews not being displayed - react-native

I am trying to display review information from the Zomato API however for some reason nothing is being displayed.
I am using a FlatList to put it all out there, but every time I compile the code nothing seems to show up.
Here is all my code regarding the subject:
<Text>REVIEWS:</Text>
{this.state.data.all_reviews_count == 0 ?
<View style={{ flex: 1, padding: 20, marginTop:0}}>
<Text style={{ color: '#000', fontWeight: 'bold' }}>No reviews for this restaurant yet</Text>
</View> :
<FlatList
keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
data={this.state.data}
renderItem={({ item }) =>
<View>
<Text>{item.all_reviews_count}</Text>
</View>}/>}
I have other data being retrieved and it's all being outputted just fine. for some reason the review section seems to be weird.
I also checked to see how reviews are displayed in the terminal and this is what I got:
"all_reviews": Object {
"reviews": Array [
Object {
"review": Array [],
},
Object {
"review": Array [],
},
Object {
"review": Array [],
},
Object {
"review": Array [],
},
Object {
"review": Array [],
},
],
}
hopefully somebody with experience with the Zomato Api can help me out

The way you retrieve & display data is wrong. Check below sample
import React, { Component } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import axios from 'axios';
export default class Example extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
all_reviews: {}
}
}
async componentDidMount() {
try {
let result = await axios.request({
method: 'GET',
url: "https://developers.zomato.com/api/v2.1/reviews?res_id=16774318",
headers: {
'Content-Type': 'application/json',
'user-key': "af26b7a0e16fb73e6a30ad33cb9c6634",
},
})
this.setState({
isLoading: false,
all_reviews: result.data
})
} catch (err) {
err => console.log(err)
}
}
render() {
return (
<View>
{
this.state.isLoading ?
<View style={{ flex: 1, padding: 20 }}>
<ActivityIndicator />
</View> :
<View>
<Text>REVIEWS:</Text>
{
this.state.all_reviews.user_reviews.length == 0 ?
<View style={{ flex: 1, padding: 20, marginTop: 0 }}>
<Text style={{ color: '#000', fontWeight: 'bold' }}>No reviews for this restaurant yet</Text>
</View> :
<FlatList
keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
data={this.state.all_reviews.user_reviews}
renderItem={({ item }) =>
<View>
<Text>{item.review.rating}</Text>
</View>}
/>
}
</View>
}
</View>
);
}
}
Change this code according to your requirements & if you have doubts feel free to ask.
Hope this helps you.

Related

Add a button "see more" in FlatList?

I use flatList to make a list of elements. I would like to show 15 elements and then add a button "see more" to show the next 15 etc.
I was about tu use this tutorial : https://aboutreact.com/react-native-flatlist-pagination-to-load-more-data-dynamically-infinite-list/
But I don't need to use fetch, I already have set up the data (state.listData) and in fact, I'm a little lost on how to adapt it...
I thought that maybe anyone could help me a little.
Thanks a lot
this.state = {
selectedId: '',
setSelectedId:'',
listData:''
}
};
renderItem = ({ item }) => {
const backgroundColor = item.id === this.selectedId ? "transparent" : "fff";
return (
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<Item
item={item}
onPress={() => this.props.navigation.navigate('UpdateTripsForm')}
style={{ backgroundColor }}
/>
<Image source={require("../../assets/images/arrow.png")} style={{width: 15, height:15, justifyContent: 'center'}}/>
</View>
);
};
initListData = async () => {
let list = await getFlights(0);
if (list) {
this.setState({
listData: list
});
}
};
render() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.listData}
renderItem={this.renderItem}
maxToRenderPerBatch={15}
keyExtractor={(item) => item.id}
extraData={this.selectedId}
/>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.view2}>
<Text style={styles.textimg2}>
{i18n.t("tripsform.action.back")}
</Text>
</View>
<Image
source={require("../../assets/images/btn-background.png")}
style={styles.tripsimg2}
/>
</TouchableOpacity>
</SafeAreaView>
);
};
}
I just tried this thanks to #Pramod 's answer :
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.flightsListitem, style]}>
<Text style={styles.h4}>{item.id}</Text>
</TouchableOpacity>
);
export default class FlightsList extends Component {
constructor(props) {
super(props);
this.state = {
selectedId: '',
setSelectedId:'',
listData:'',
page:1,
perPage:2,
loadMoreVisible:true,
displayArray:[]
}
};
renderItem = ({ item }) => {
const backgroundColor = item.id === this.selectedId ? "transparent" : "fff";
return (
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<Item
item={item}
onPress={() => this.props.navigation.navigate('UpdateTripsForm')}
style={{ backgroundColor }}
/>
<Image source={require("../../assets/images/arrow.png")} style={{width: 15, height:15, justifyContent: 'center'}}/>
</View>
);
};
initListData = async () => {
let list = await getFlights(0);
if (list) {
this.setState({
listData: list
});
}
};
componentDidMount(){
this.setNewData()
// console.log(tempArray)
}
setNewData(){
var tempArray=[]
if(this.state.listData.length == this.state.displayArray.length){
this.setState({
loadMoreVisible:false
})
}else{
for(var i=0; i<(this.state.page*this.state.perPage); i++){
tempArray.push(this.state.listData)
}
this.setState({
displayArray: tempArray,
loadMoreVisible:true
})
}
}
loadMore(){
this.setState({
page: this.state.page+1
},()=>{
this.setNewData()
})
}
async UNSAFE_componentWillMount() {
this.initListData();
}
render() {
return (
<ImageBackground
source={require("../../assets/images/background.jpg")}
style={styles.backgroundImage}
>
<Header
backgroundImage={require("../../assets/images/bg-header.png")}
backgroundImageStyle={{
resizeMode: "stretch",
}}
centerComponent={{
text: i18n.t("mytrips.title"),
style: styles.headerComponentStyle,
}}
containerStyle={[styles.headerContainerStyle, { marginBottom: 0 }]}
statusBarProps={{ barStyle: "light-content" }}
/>
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.displayArray}
renderItem={this.renderItem}
keyExtractor={(item) => item.id}
extraData={this.selectedId}
/>
{this.state.loadMoreVisible == true?
<Button style={{width:'100%', height:10, backgroundColor:'green', justifyContent:'center', alignItems:'center'}}
title = 'load more'
onPress={()=>{this.loadMore()}}>
</Button>:null}
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.view2}>
<Text style={styles.textimg2}>
{i18n.t("tripsform.action.back")}
</Text>
</View>
<Image
source={require("../../assets/images/btn-background.png")}
style={styles.tripsimg2}
/>
</TouchableOpacity>
</SafeAreaView>
</ImageBackground>
);
};
}
the flatlist is not displayed : I get :
You can user pagination method with per page limit so that you can have granular control
Load the array per page when component mount
On every click increase the per page and based on per page update data of your flat list
And also put a flag which will check when the data has ended which will help to hide the load more button when data ends
Working example: https://snack.expo.io/#msbot01/suspicious-orange
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
SafeAreaView,
SectionList,
Switch,
FlatList
} from 'react-native';
import Constants from 'expo-constants';
import Icon from 'react-native-vector-icons/FontAwesome';
import AwesomeIcon from 'react-native-vector-icons/FontAwesome';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
page:1,
perPage:2,
loadMoreVisible:true,
DATA: [{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'fourth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'fifth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29sd72',
title: 'sixth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29dr72',
title: 'seventh Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d7w2',
title: 'Eight Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29ad72',
title: 'Nineth Item',
},
{
id: '58694a0f-3da1-471f-bd96-14557d1e29d72',
title: 'Tenth Item',
}],
displayArray:[]
}
}
componentDidMount(){
this.setNewData()
// console.log(tempArray)
}
setNewData(){
var tempArray=[]
if(this.state.DATA.length == this.state.displayArray.length){
this.setState({
loadMoreVisible:false
})
}else{
for(var i=0; i<(this.state.page*this.state.perPage); i++){
tempArray.push(this.state.DATA[i])
}
this.setState({
displayArray: tempArray,
loadMoreVisible:true
})
}
}
loadMore(){
this.setState({
page: this.state.page+1
},()=>{
this.setNewData()
})
}
render() {
return (
<View style={{ flex: 1 }}>
<FlatList
data={this.state.displayArray}
renderItem={({item})=>
<View style={{flexDirection:'row'}}>
<Text style={{fontSize:20}}>{item.title} </Text>
</View>
}
keyExtractor={item => item.id}
/>
{this.state.loadMoreVisible == true?
<View style={{width:'100%', height:10, backgroundColor:'green', justifyContent:'center', alignItems:'center'}} onClick={()=>{this.loadMore()}}>Load more</View>:null
}
</View>
);
}
}
Set data in state (already done ==> this.state.listData)
Set counter in state (initialize with 1)
Set 15 first elements in state (you can name it "renderedData" or something like that) and then increase cuonter to 1
Add a function that increases the "renderedData" by 15 items by increasing the counter by one
Add Footer component to the list which will call the function you created in stage 3
To take only 15( or 30/45/60 etc..) items from the list you can do something like this:
this.setState({ renderedItem: listData.slice(0, counter*15) })

React Native retrieving API data source.uri should not be an empty string

I am trying to retrieve data from an API (https://developers.zomato.com/documentation) and get title of restaurants and an image with it. However when I try to load an image I get a warning source.uri should not be an empty string.
Here is my code as it stands:
async componentDidMount() {
let id = this.props.navigation.state.params.category
let result;
try {
result = await axios.request({
method: 'get',
url: `https://developers.zomato.com/api/v2.1/search?category=${id}`,
headers: {
'Content-Type': 'application/json',
'user-key': "a31bd76da32396a27b6906bf0ca707a2",
},
})
} catch (err) {
err => console.log(err)
}
this.setState({
isLoading: false,
data: result.data.restaurants
})
}
render() {
return (
<View>
{
this.state.isLoading ?
<View style={{ flex: 1, padding: 20 }}>
<ActivityIndicator style={{color:'red'}} />
</View> :
(
this.state.data.length == 0 ?
<View style={{ flex: 1, padding: 20 }}>
<Text style={{ color: '#000', fontWeight: 'bold' }}>No restaurants from selected category</Text>
</View> :
<FlatList
style={{ marginBottom: 80 }}
keyExtractor={item => item.id}
data={this.state.data}
renderItem={({ item }) =>
<TouchableHighlight onPress={()=> console.log(item.restaurant.thumb)}>
<Card image={item.restaurant.thumb} style={styles.container}>
<Image resizeMode='contain' source={{ uri: item.restaurant.thumb }}/>
<Text style={{color:'#000',fontWeight:'bold'}}>{item.restaurant.name} </Text>
</Card>
</TouchableHighlight>
}
/>
)
}
</View>
);
}
as you can see when I touch the any of the cards I am console logging the link of the image uri and it shows up perfectly. Why is that when the app loads the images they are empty strings yet when I load it though console log the link shows up perfectly?
I am using axios to load my API
here is an expo snack link: https://snack.expo.io/r1XTaw4JU
So i got 2 issues, one is in the card component you were not providing the uri properly it should be image={{uri:item.restaurant.thumb}} and secondly for newyork your entity id must be
To search for 'Italian' restaurants in 'Manhattan, New York City',
set cuisines = 55, entity_id = 94741 and entity_type = zone
Its as per zomato docs,so do check out that. and find expo link : expo-snack
import React from 'react';
import {
View,
Text,
FlatList,
StyleSheet,
Button,
TouchableHighlight,
ActivityIndicator,
} from 'react-native';
import { createAppContainer } from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import { Card, Image } from 'react-native-elements';
import Constants from 'expo-constants';
import axios from 'axios';
export default class CategoryScreen extends React.Component {
constructor(props){
super(props);
this.state={
data : [],
isVisible: true,
city : '94741'
}
}
async componentDidMount() {
let id = "3"
let city = this.state.city
let result;
try {
result = await axios.request({
method: 'get',
url: `https://developers.zomato.com/api/v2.1/search?entity_id=${city}&entity_type=zone&category=${id}`,
headers: {
'Content-Type': 'application/json',
'user-key': "a31bd76da32396a27b6906bf0ca707a2",
},
})
} catch (err) {
err => console.log(err)
}
this.setState({
isLoading: false,
data: result.data.restaurants
})
console.log(result)
console.log(data)
}
render() {
return (
<View>
{
this.state.isLoading ?
<View style={{ flex: 1, padding: 20 }}>
<ActivityIndicator style={{color:'red'}} />
</View> :
(
this.state.data.length == 0 ?
<View style={{ flex: 1, padding: 20 }}>
<Text style={{ color: '#000', fontWeight: 'bold' }}>No restaurants from selected category</Text>
</View> :
<FlatList
style={{ marginBottom: 80 }}
keyExtractor={item => item.id}
data={this.state.data}
renderItem={({ item }) =>
<TouchableHighlight onPress={()=> alert(item.restaurant.location.city)}>
<Card image={{uri:item.restaurant.thumb}} style={styles.container}>
<Text style={{color:'#000',fontWeight:'bold'}}>{item.restaurant.name} </Text>
</Card>
</TouchableHighlight>
}
/>
)
}
</View>
);
}
};
const styles = StyleSheet.create({
});

How to lazy load with specific number of items in scrollview in react native?

I am trying to develop an app where a screen contains news feed loading data from a certain api which loads around 100 of the data. I would like to paginate it like first load 10 data then scroll more to get more data and so on.Which is also referenced as infinite scrolling.
You should use below example for pagination in scrollview or flatlist. Paste your url(API) here and run.
import React, { Component } from "react"
import {
View,
Text,
TouchableOpacity,
StyleSheet,
FlatList,
Platform,
ActivityIndicator
} from "react-native"
class FlatlistPagination extends Component {
constructor() {
super()
this.state = {
loading: true,
//Loading state used while loading the data for the first time
serverData: [],
//Data Source for the FlatList
fetching_from_server: false
//Loading state used while loading more data
}
this.offset = 1
//Index of the offset to load from web API
}
componentDidMount() {
fetch("http://aboutreact.com/demo/getpost.php?offset=" + this.offset)
//Sending the currect offset with get request
.then(response => response.json())
.then(responseJson => {
//Successful response from the API Call
this.offset = this.offset + 1
//After the response increasing the offset for the next API call.
this.setState({
serverData: [...this.state.serverData, ...responseJson.results],
//adding the new data with old one available in Data Source of the List
loading: false
//updating the loading state to false
})
})
.catch(error => {
console.error(error)
})
}
loadMoreData = () => {
//On click of Load More button We will call the web API again
this.setState({ fetching_from_server: true }, () => {
fetch("http://aboutreact.com/demo/getpost.php?offset=" + this.offset)
//Sending the currect offset with get request
.then(response => response.json())
.then(responseJson => {
//Successful response from the API Call
this.offset = this.offset + 1
//After the response increasing the offset for the next API call.
this.setState({
serverData: [...this.state.serverData, ...responseJson.results],
//adding the new data with old one available in Data Source of the List
fetching_from_server: false
//updating the loading state to false
})
})
.catch(error => {
console.error(error)
})
})
};
renderFooter() {
return (
//Footer View with Load More button
<View style={styles.footer}>
<TouchableOpacity
activeOpacity={0.9}
onPress={this.loadMoreData}
//On Click of button calling loadMoreData function to load more data
style={styles.loadMoreBtn}
>
<Text style={styles.btnText}>Load More</Text>
{this.state.fetching_from_server ? (
<ActivityIndicator color="white" style={{ marginLeft: 8 }} />
) : null}
</TouchableOpacity>
</View>
)
}
render() {
return (
<View style={styles.container}>
{this.state.loading ? (
<ActivityIndicator size="large" />
) : (
<FlatList
style={{ width: "100%" }}
keyExtractor={(item, index) => index}
data={this.state.serverData}
renderItem={({ item, index }) => (
<View style={styles.item}>
<Text style={styles.text}>
{item.id}
{"."}
{item.title.toUpperCase()}
</Text>
</View>
)}
ItemSeparatorComponent={() => <View style={styles.separator} />}
ListFooterComponent={this.renderFooter.bind(this)}
//Adding Load More button as footer component
/>
)}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
paddingTop: 30
},
item: {
padding: 10
},
separator: {
height: 0.5,
backgroundColor: "rgba(0,0,0,0.4)"
},
text: {
fontSize: 15,
color: "black"
},
footer: {
padding: 10,
justifyContent: "center",
alignItems: "center",
flexDirection: "row"
},
loadMoreBtn: {
padding: 10,
backgroundColor: "#800000",
borderRadius: 4,
flexDirection: "row",
justifyContent: "center",
alignItems: "center"
},
btnText: {
color: "white",
fontSize: 15,
textAlign: "center"
}
})
export default FlatlistPagination

how to pass data from one screen to other screen using react-native-router

I'm very new to react-native.
can any one please tell me how to pass data to another screen using react-native-router.
I have a flatlist when a list item is clicked it will display an alert meassage , when i click on ok button it should display the RxNumberin next screen.enter image description here
here is my full class
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
FlatList,
Image,
Alert
} from 'react-native';
import { Actions } from 'react-native-router-flux';
import colors from '../styles/colors';
class MedicineFlatList extends Component {
constructor(props) {
super(props);
this.state = {
refreshing: false,
};
}
componentDidMount() {
fetch('https://api.myjson.com/bins/96ebw')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
//dataSource: responseJson,
dataSource: responseJson.map(item => item.ReadyForPickups).reduce((acc, currValue) => { return acc.concat(currValue); }, [])
},
);
})
.catch((error) => {
console.error(error);
});
}
GetItem(RxNumber) {
Alert.alert(
'RxNumber',
RxNumber,
[
{ text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel' },
{ text: 'OK', onPress: (item) => Actions.listitem({ item: item.RxDrugName }) },
],
{ cancelable: false },
);
}
listItem=(item) => {
return (
<Text style={styles.itemName}>{item.RxDrugName }</Text>
);
}
keyExtractor = (index) => {
return index.toString();
}
renderItem = ({ item }) => {
return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{item.RxDrugName}</Text>
<Text style={styles.itemLastMessage} onPress={this.GetItem.bind(this, item.RxNumber)}>{item.RxNumber}</Text>
</View>
<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{item.StoreNumber}</Text>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={require('../assets/right_arrow_blue.png')} />
</View>
</View>
</View>
);
}
renderSeparator() {
return <View style={styles.separator} />;
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
keyExtractor={this.keyExtractor}
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator.bind(this)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
paddingHorizontal: 30,
backgroundColor: colors.white
},
itemBlock: {
flexDirection: 'row',
paddingVertical: 15,
},
itemMeta: {
justifyContent: 'center'
},
itemName: {
fontSize: 16,
color: colors.black_two,
paddingBottom: 10
},
itemLastMessage: {
fontSize: 14,
color: colors.black_two,
},
status: {
fontSize: 14,
color: colors.blue,
fontWeight: 'bold'
},
separator: {
borderRadius: 4,
borderWidth: 1,
borderColor: colors.light_gray,
},
footerStyle: {
flexDirection: 'row',
flex: 1,
paddingVertical: 10,
justifyContent: 'flex-end'
}
});
export default MedicineFlatList;
Thanks everyone I got the answer.
if your are using react-native-router-flux which i recommend
https://www.npmjs.com/package/react-native-router-flux
it is something like that
Action.Screen2({id : 1})
and on screen2
this.props.id will be 1
and if your are using react navigation
read the doc it will help you
it is something like this
this.props.navigation.navigate('Screen2', {data: 'some-stuff'})
and you can access data in other screen like this.
this.props.navigation.state.params('data')
Tulasi, Roozbeh Mohammadzadeh is correct and answers your question with the use of react-native-router-flux; however, as you continue you may wish to explore using redux or another alternative Appstate system, there are a few.
Reason: Passing data will work for small projects, but larger projects passing up and down the grandparent, parent, child component chain becomes cumbersome and inefficient to troubleshoot and/or maintain.
But to answer your question about passing data using react-native-router see the following right above the Todos section : https://www.npmjs.com/package/react-native-router
The this.props.toRoute() callback prop takes one parameter (a JavaScript object) which can have the following keys:
name: The name of your route, which will be shown as the title of the
navigation bar unless it is changed.
component (required): The React
class corresponding to the view you want to render.
leftCorner:
Specify a component to render on the left side of the navigation bar
(like the "Add people"-button on the first page of the Twitter app)
rightCorner: Specify a component to render on the right side of the
navigation bar
titleComponent: Specify a component to replace the
title. This could for example be your logo (as in the first page of
the Instagram app)
headerStyle: change the style of your header for
the new route. You could for example specify a new backgroundColor
and the router will automatically make a nice transition from one
color to the other!
data: Send custom data to your route.

State does not change until the second button press? Adding a call back throws an error "invariant violation: invalid argument passed"

I'm trying to render a Flatlist that contains a store name. Upon clicking the store name, more information about the store should be displayed.
I attempted to change state and then use
{this.renderMoreDetails(item) && this.state.moreDetailsShown}
to get the additional information to appear. However, it was clear via console.log that state was only changed after a second button press.
From what I read in this article 1 and this article 2 it seemed as though I needed a callback function as an additional parameter to my setState().
I tried adding a callback function(probably incorrect, but I'm extremely lost at this point) and only got more errors.
I know that I have access to all of the data from renderItem inside FlatList. How do I make it appear upon click?
import React, { Component } from 'react';
import {
View,
FlatList,
Text,
TouchableWithoutFeedback,
ListView,
ScrollView
} from 'react-native'
import { NavigationActions } from 'react-navigation';
import { Header, Card, CardSection } from '../common';
import Config from '../Config';
export default class Costco extends Component<Props> {
constructor(props) {
super(props);
this.state = {
stores: [],
selectedItem: {id: null},
};
}
componentWillMount() {
const obj = Config.costcoThree;
const costcoArr = Object.values(obj);
this.setState({
stores: costcoArr,
})
}
renderListOfStores() {
return <FlatList
data={this.state.stores}
renderItem={ ({item}) => this.singleStore(item)}
keyExtractor={(item) => item.id}
extraData={this.state.selectedItem} />
}
singleStore(item) {
console.log(this.state.selectedItem.id)
return item.id === this.state.selectedItem.id ?
<TouchableWithoutFeedback
onPress={() => this.selectStore(item)}
>
<View>
<Text>{item.branchName}</Text>
<Text>Opening Time {item.openingTime}</Text>
<Text>Closing Time {item.closingTime}</Text>
<Text>Address {item.dongAddKor}</Text>
</View>
</TouchableWithoutFeedback>
:
<TouchableWithoutFeedback>
<View>
<Text>{item.branchName}</Text>
<Text>Only showing second part</Text>
</View>
</TouchableWithoutFeedback>
}
selectStore(item) {
this.setState({selectedItem: item});
console.log('repssed');
}
render() {
return(
<ScrollView>
<Header headerText="Costco"/>
<Text>hello</Text>
{this.renderListOfStores()}
</ScrollView>
)
}
}
as a workaround you can have a state that maintain your selected item to expand(or something like another view) and then you can use some conditions to work for render your flat list data.
Consider the below code and let me know if you need some more clarification.
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,FlatList,TouchableNativeFeedback,
View
} from 'react-native';
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
response: [],
selectedItem: {id: null},
};
}
userListLayout() {
const {response} = this.state;
return <FlatList data={response} renderItem={ ({item}) => this.singleUserLayout(item)} keyExtractor={(item) => item.email} extraData={this.state.selectedItem} />
}
singleUserLayout(item) {
return item.id == this.state.selectedItem.id ?
<TouchableNativeFeedback onPress={() => this.userSelected(item)}>
<View style={{flex:1, borderColor: 'black', borderWidth: 1}}>
<Text style={{padding: 10, fontSize: 25}}>{item.email}</Text>
<Text style={{padding: 10,fontSize: 20}}>{item.name}</Text>
</View>
</TouchableNativeFeedback>
: <TouchableNativeFeedback onPress={() => this.userSelected(item)}><Text style={{padding: 10,fontSize: 20}}>{item.email}</Text></TouchableNativeFeedback>
}
userSelected(item) {
console.log(item)
this.setState({selectedItem: item})
}
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users")
.then(data => data.json())
.then(response => this.setState({response}))
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>HI THERE</Text>
{this.userListLayout()}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});