How to Integrate react-native-swiper using flatlist - javascript

I was trying to integrate react-native-swiper, which loads videos in it.
I am looking for a way to integrate it with a flat list. but the data is not loading properly, is there any alternative way to load data using flat list (using array.map())
export default class HomeTab extends Component {
render() {
return (
<FlatList
data={Data}
keyExtractor={(item, index) => item.id}
renderItem={({item}) =>
<Swiper style={styles.wrapper}
showsButtons={false}
horizontal={true}
loop={false}
index={item.id}
activeDot={
<View></View>
}
dot={
<View></View>
}
>
<View style={styles.slide1}>
<Video
source={{uri: item.media}} // Can be a URL or a local file.
ref={(ref) => {
this.player = ref
}}
resizeMode={'contain'}
style={styles.backgroundVideo}
/>
</View>
</Swiper>
}
/>
)
}
}
using npm package: react-native-swiper https://www.npmjs.com/package/react-native-swiper

try to use this lib, cause react-native-swiper-flatlist it has flatlist inside
Example below:
<SwiperFlatList
autoplay
autoplayDelay={3}
index={3}
autoplayLoop
data={items}
renderItem={({item}) => // Standard Image
<View style={[styles.child, { backgroundColor: '#000' }]}>
<Image
source={{uri:item.key}}
style={styles.checkoutSliderImage}
/>
<Text>{item.key}</Text>
</View>
}
showPagination
/>

Related

renderItems problems in react-native FlatList

I am trying to deliver data from data.json to video.js
<Image source={{ uri: video.snippet.thumbnails.medium.url }}
style={{ height: 200 }} />
and i want to make this file renderd in flatlist
<FlatList
showsHorizontalScrollIndicator={false}
data={data.items}
keyExtractor={(item) => item.id}
renderItem={(video) => <Video data={data.items}/>}
/>
when i try to render one item like data={data.items[0]} is shows up well, but it cant render some items the error says
TypeError: undefined is not an object (evaluating 'video.snippet.thumbnails') *
thanks in advance
This might help
// Change your `renderItem` like
renderItem={({item}) => <Video data={item}/>}
Video.js
const { data } = this.props;
return (
<View style={styles.container}>
<Image
source={{ uri: data.snippet.thumbnails.medium.url }}
style={{ height: 200 }}
/>
......
<View style={styles.videoDetails}>
<Text style={styles.videoTitle}>{data.snippet.title}</Text>
<Text style={styles.videoStat}>
{data.snippet.channelTitle} • {nFormatter(data.statistics.viewCount)} •{" "}
{date(data.snippet.publishedAt)}
</Text>
</View>
......
</View>
);

React native, edit data from another screen

I made 2 screens one home screen and 2nd edit screen I need to edit data of home screen from edit screen and save it and that data should also update in home and detail screen. How can I do this without redux or context. Can anyone tell me.
Home.js
class Home extends Component {
state = {
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
],
};
render() {
return (
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => this.props.navigation.navigate("Edit", item)}
style={styles.Edit}
>
<MaterialCommunityIcons
name="playlist-edit"
color="green"
size={35}
/>
</TouchableOpacity>
<Card
title={item.title}
subTitle={item.des}
image={item.image}
onPress={() => this.props.navigation.navigate("Details", item)}
/>
</>
)}
/>
Edit.js
class ListDetails extends Component {
render() {
const listing = this.props.route.params;
return (
<View>
<Image style={styles.image} source={listing.image} />
<View style={styles.detailContainer}>
<AppTextInput value={listing.title} />
<AppTextInput value={listing.des} />
</View>
<AppButton
text="Save"
onPress={() => this.props.navigation.goBack("Home")}
/>
</View>
Details.js
const listing = this.props.route.params;
return (
<View>
<Image style={styles.image} source={listing.image} />
<View style={styles.detailContainer}>
<Text style={styles.title}>{listing.title}</Text>
<Text style={styles.des}>{listing.des}</Text>
</View>
</View>
);
You can pass a function from your home screen to setState for it in your edit screen. In case navigating to edit screen causes the home screen unmounted, you can change the navigate method to push of stack navigator (I haven't tested yet). The code now should look like:
HomeScreen.js:
onEdit=(data)=>{
setState(...);
}
...
<TouchableOpacity
activeOpacity={0.7}
onPress={() => this.props.navigation.navigate("Edit", {item, onEdit})} //use push instead if error occured
style={styles.Edit}
>
...
Edit.js
class ListDetails extends Component {
render() {
const {item:listing, onEdit} = this.props.route.params;
return (
<View>
<Image style={styles.image} source={listing.image} />
<View style={styles.detailContainer}>
<AppTextInput value={listing.title} />
<AppTextInput value={listing.des} />
</View>
<AppButton
text="Save"
onPress={() => { onEdit(...); this.props.navigation.goBack("Home");}}
/>
</View>

Show Empty list message only after Loader get ended in React Native using Flat list

I have a flat list, which gets its data source as a state. Actually, this data is from firebase, and i have been using redux. So, the data is fetched in the actions, and using callback i get the data to state.
What i want to achieve is, when there is no data found from the api, An empty list message should be show in the view. Actually , i achieved this using "ListEmptyComponent". But whats happening is the screen starts with empty message, and the spinner loads below it, and then if data found the message goes away as well as spinner.
But, what i wanted is, when the view gets rendered the first thing everyone should see is the spinner, and then if data empty spinner hides then empty list message displays.
How to achieve this ?
My Action :
export const fetchOrderHistory = (phone, callback) => {
return (dispatch) => {
dispatch({ type: START_SPINNER_ACTION_FOR_ORDER_HISTORY })
firebase.database().ref('orders/'+phone)
.on('value', snapshot => {
const snapShotValue = snapshot.val();
callback(snapShotValue);
dispatch ({ type: ORDER_HISTORY_FETCHED , payload: snapshot.val()});
dispatch({ type: STOP_SPINNER_ACTION_FRO_ORDER_HISTORY })
});
};
};
My Flat List & spinner:
<FlatList
data={this.state.historyOfOrders}
keyExtractor={item => item.uid}
ListEmptyComponent={this.onListEmpty()}
renderItem={({ item }) => (
<Card
containerStyle={{ borderRadius: 5 }}
>
<View style={styles.topContainerStyle}>
<View>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('ViewOrderScreen', {itemsOfOrder: item}) }
>
<View style={styles.viewOrderContainer}>
<View style={styles.viewOrderTextContainer}>
<Text style={styles.viewOrderTextStyle}>View Order</Text>
</View>
<Icon
name='ios-arrow-forward'
type='ionicon'
color='#ff7675'
/>
</View>
</TouchableOpacity>
</View>
</View>
</View>
</Card>
)}
/>
{this.props.isSpinnerLoading &&
<View style={styles.loading}>
<ActivityIndicator size="large" color="#03A9F4"/>
</View> }
My Call back at componentWillMount which set state:
componentWillMount() {
this.props.fetchOrderHistory((this.props.phone), (snapShotValue)=> {
const userOrderHistory = _.map(snapShotValue, (val,uid) => ({uid, ...val}))
this.setState({ historyOfOrders: userOrderHistory })
});
}
My EmptyList Message:
onListEmpty = () => {
return <View style={{ alignSelf: 'center' }}>
<Text style={{ fontWeight: 'bold', fontSize: 25 }}>No Data</Text>
</View>
}
My State:
state = { historyOfOrders: "" }
I am getting the spinner values from the reducers, using mapStateToProps.
Kindly Guide me, through
you have to do two things for that.
First, show Flatlist only if the loader is stopped. Second, set default value of this.state.historyOfOrders is null and check if this.state.historyOfOrders not null then only show Flatlist.
Here is a code:
{(!this.props.isSpinnerLoading && this.state.historyOfOrders != null) ?
(
<FlatList
data={this.state.historyOfOrders}
keyExtractor={item => item.uid}
ListEmptyComponent={this.onListEmpty()}
renderItem={({ item }) => (
<Card containerStyle={{ borderRadius: 5 }}>
<View style={styles.topContainerStyle}>
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('ViewOrderScreen', {itemsOfOrder: item}) }>
<View style={styles.viewOrderContainer}>
<View style={styles.viewOrderTextContainer}>
<Text style={styles.viewOrderTextStyle}>View Order</Text>
</View>
<Icon
name='ios-arrow-forward'
type='ionicon'
color='#ff7675'
/>
</View>
</TouchableOpacity>
</View>
</View>
</Card>
)}
/>
) : null
}
With this condition, even if you want loader above Flatlist you can do that.
The path you should take is rendering only the spinner when the loading flag is set and rendering the list when loading flag is false.
Your render method should be like below
render()
{
if(this.props.isSpinnerLoading)
{
return (<View style={styles.loading}>
<ActivityIndicator size="large" color="#03A9F4"/>
</View> );
}
return (/** Actual List code here **/);
}

I cannot figure out how to make ListView work properly

I am trying to render a list in React Native, however, nothing ever shows. I am logging the list before render as well and it is showing that the data field is being populated, but nothing is being shown.
This is the ListView code that I am trying that is NOT working.
This is the way that I am currently rendering the list. This method is working for me.
The reason that I want to use ListView instead of the current method that I am using is because I was reading from the documentation that ListView has better properties and performance.
Thank you!
Try destructuring correctly your item in renderItem. I mean:
<FlatList
data={this.state.users}
renderItem={({item}) => {
return (
<View>
<Image source={{uri: item.image}} style={{width: 150, height: 150}} />
<Text>{item.login}</Text>
</View>
)
}}
keyExtractor={(user) => user.id}
/>
Or, if you prefer to call it as info, define a function:
renderItem = (info) => {
return (
<View>
<Image source={{uri: info.image}} style={{width: 150, height: 150}} />
<Text>{info.login}</Text>
</View>
)
}
And call it like
<FlatList
data={this.state.users}
renderItem={({item}) => this.renderItem(item)}
keyExtractor={(user) => user.id}
/>
See more in the offical doc
You need to extract the item property from your data property in the FlatList
<FlatList
data={this.state.users}
renderItem={({item}) => {
return (
<View>
<Image source={{uri: item.image}} style={{width: 150, height: 150}} />
<Text>{item.login}</Text>
</View>
)
}}
keyExtractor={(user) => user.id}
/>
Note {item} in the renderItem callback
Another example
<FlatList
data={this.state.users}
renderItem={(data) => {
return (
<View>
<Image source={{uri: data.item.image}} style={{width: 150, height: 150}} />
<Text>{data.item.login}</Text>
</View>
)
}}
keyExtractor={(user) => user.id}
/>

Correct way to iterate this data and render section headers and items?

my JSON response looks like this
I would like to render the name i.e. pasta/pizza as header(which can be collapsed or opened) and the items i.e. types of pizza/pasta inside the respective category.
I am using react native, I tried using map and ListView
return (this.props.item.items.map((res) => {
console.log(res);
return (
<View>
<View style={CardContainer}>
<Text>{res.title}</Text>
<Image
source={{ uri: res.photo }}
style={imageStyle}
/>
</View>
</View>
);
})
);
but they return single objects so when I associate a onPress event over the category i.e. pasta it is registered twice which is undesirable as a click would mean expanding that category i.e. pasta.
Please let me know If i should change the JSON structure to make it efficient, this is a JSON response for menu card
EDIT: I tried the following but cannot get it to display result
renderItem() {
return (
<View>
{
this.props.menu.map(({ name, items }) => {
<View>
<Text>{name}</Text>
</View>
items.map((resp) => {
<View>
<Text>{resp.title}</Text>
</View>
});
})
}
</View>
);
}
<View>
{this.props.item.items.map((res) => (
<View>
<Header>
{ res.name }
</Header>
{ res.items.map(item => (
<View style={CardContainer}>
<Text>{item.title}</Text>
<Image
source={{ uri: item.photo }}
style={imageStyle}
/>
</View>
)}
</View>
)))}
</View>
IMO, a little more readable
render() {
const { item: { items: allItems } } = this.props;
return (
<View>
{ allItems.map(({ name, items }) => (
<Header>{ name }</Header>
{ items.map(({ title, photo }) => (
<View style={CardContainer}>
<Text>{title}</Text>
<Image
source={{ uri: photo }}
style={imageStyle}
/>
</View>
)}
)}
</View>
)
}

Categories