flatlist pagination make app really slow on android - react-native

i am using a flat list for rendering data from server but the problem i have is when i render lots of data my app become too much slow
<FlatList
data={this.state.product}
numColumns={2}
inverted
renderItem={({item}) =>
<TouchableOpacity style={styles.homeGride}>
<View style={styles.offer}>
<Text style={styles.offerText}>{item.offer}%</Text>
</View>
<ImageBackground style={styles.homeImage} source={{uri:`${item.img}`}}>
</ImageBackground>
<Text style={styles.homeProductText}>{item.title}</Text>
<View style={{flexDirection:"row-reverse"}}>
<Text style={{flex:1,fontFamily:"FaNum"}}>{item.price}</Text>
<Text style={{flex:1,fontFamily:"FaNum"}}>{item.new_price}</Text>
</View>
<Button small danger>
<Text style={{padding:5}}>خرید</Text>
</Button>
</TouchableOpacity>
}
keyExtractor={({id}, index) => id}
/>

you should consider using onEndReached attribute of FlatList.
first define a page state
this.setState({page:1});
when fetching data from server send page parms to chunk the data
for Ex. in laravel server side framework do this :
$data = Data::where("sth","sth")->paginate(10,'page');
now in your react native application :
<FlatList
data={this.state.product}
numColumns={2}
inverted
onEndReached={this.handleLoadMore}
onEndThreshold={10}
renderItem={({item}) =>
..sth..
}
keyExtractor={({id}, index) => id}
/>
now in handleLoadMore add 1 number to page state and again fetch data
this will help you improve your speed and performance and fetch other data when they are needed !

I recommend you use the recyclerListView component
it has better performance for android devices.

Related

Rerender stak navigation ? react native

I have a menu with 3 levels in my app, and I would like just to refresh data in my flat list more than using 3 different screens (like I'm doing now), but, I don't know, how to manage the back button.
Can you help me?
<View style={styles.container}>
<Navbar enableBackButton title={t('product.menu.LABEL_CATEGORY')} />
<FlatList
style={[styles.container, { paddingBottom: insets.bottom }]}
data={menuData}
keyExtractor={(item) => item.catalog.code}
renderItem={({ item }) => <ItemMenu name={item.catalog.name} goTo="Menu2" subItem={item} />}
/>
</View>

react native - I cannot scrolling down with two flatlist

I can scroll only in case when I change SafeAreaView to ScrollView but I get this error
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
{subCategoryIsLoading ? (
<ActivityIndicator
size='large'
color={primColor}
style={{marginTop: 150}}
/>
) : (
<SafeAreaView>
<View style={styles.containerSubCategory}>
<FlatList
showsVerticalScrollIndicator={false}
data={filterCatTrue()}
keyExtractor={item => item._id}
renderItem={({item}) => {
return (
<View style={styles.containerImages}>
<TouchableHighlight onPress={() => console.log(item._id)}>
<Image
source={{
uri: `${urlImages}subCategories/${item.image}`,
}}
style={styles.imageSubCategory}
/>
</TouchableHighlight>
</View>
)
}}
/>
<FlatList
horizontal={false}
numColumns={2}
showsVerticalScrollIndicator={false}
columnWrapperStyle={{
justifyContent: 'space-between',
}}
data={filterCatFalse()}
keyExtractor={item => item._id}
contentInset={{bottom: 60}}
renderItem={({item}) => {
return (
<View style={styles.containerImagesWide}>
<TouchableHighlight>
<Image
source={{
uri: `${urlImages}subCategories/${item.image}`,
}}
style={styles.imageSubCategoryWide}
/>
</TouchableHighlight>
</View>
)
}}
/>
</View>
</SafeAreaView>
)}
Virtualized lists, that means 'SectionList' and 'FlatList' for example, are performance-optimized meaning they improve memory consumption when using them to render large lists of content. The way this optimization works is that it only renders the content that is currently visible in the window, usually meaning the container/screen of your device. It also replaces all the other list items same sized blank space and renders them based on your scrolling position.
Now If you put either of these two lists inside a ScrollView they fail to calculate the size of the current window and will instead try to render everything, possibly causing performance problems, and it will of course also give you the warning mentioned before.
Check this post, it perfectly explains your problem.

Load items from API in reverse order

I have a react native app that is retrieving APIs.
However, instead of retrieving from item[0] to item[93], I wanted to reverse it so that it presents the data from item[93] at the top, followed by item[92], etc.
Hence, I tried to include this in my flatlist:
inverted={true}
However, in doing so, when i load the app, it will still load from [0], but keep including the next items above it over and over.
How do I also load the info from item[93] to item[0]?
Thanks so much!
My flatlist looks like that:
return (
<View style={styles.background}>
<FlatList
data={this.state.dataSource}
keyExtractor={this._keyExtractor}
inverted={true}
renderItem={({ item }) => (
<Card>
<CardItem>
<View style={styles.container}>
<Image style={styles.profilepic}
source={{
uri: item.links.mission_patch
// from API docs
}}
/>
</View>
<View style={styles.userinfo}>
<Text style={styles.content}>
Flight Number: {item.flight_number}
Mission Name: {item.mission_name}
{item.details}
</Text>
</View>
</CardItem>
</Card>
)}
/>
</View>
);
}
}
You can try the Array.reverse() like so:
<FlatList
data={this.state.dataSource.reverse()}
//

Algolia and React Native FlatList ListHeaderComponent

I you put an Algolia connected component in a header of a FlatList it's as if it enters an infinite loop of queries. The connectInfiniteHits runs constantly.
This is really annoying if you like to put some simple filters in the headers of a list of hits.
My setup is like this:
I have a FlatList that is wrapped by the connectInfiniteHits HOC.
The ListHeaderComponent contains a component this is wrapped by the connectRefinementList HOC. The same problem occurs with a connectSearchBox HOC.
Has anyone seen this and found a solution?
I manage to make it work with those lines:
const RefinementList = connectRefinementList(({ items, refine }) => (
<View>
{items.map(item => (
<TouchableOpacity key={item.label} onPress={() => refine(item.value)}>
<Text style={{ fontWeight: item.isRefined ? '600' : 'normal' }}>
{item.label}
</Text>
</TouchableOpacity>
))}
</View>
));
const InfiniteHits = connectInfiniteHits(({ hits, hasMore, refine }) => (
<FlatList
data={hits}
keyExtractor={item => item.objectID}
onEndReached={() => hasMore && refine()}
ListHeaderComponent={<RefinementList attribute="brand" />}
renderItem={({ item }) => (
<View>
<Text>{JSON.stringify(item).slice(0, 100)}</Text>
</View>
)}
/>
));
Note that I'm not using the function version which indeed breaks.

How do I render different data types from a fetched json?

I was using...
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.username} {item.name}</Text>}
keyExtractor={({id}, index) => id}
/>
...to render two texts in React Native but now I've got an uri in my json...
How do I render the image in an IM style (thumbnail, username and name)?
Add a renderItem method and then put everything you need in there. Once you make the renderItem method you can throw it into your FlatList.
renderItem({ item }) {
return (
<View>
<Image
source={{uri: item.uri}}
/>
<Text>
{item.username}
</Text>
<Text>
{item.name}
</Text>
</View>
);
}
Then use the method inside the FlatList (the .bind makes sure it stays in the right context)
<FlatList
data={this.state.dataSource}
renderItem={this.renderItem.bind(this)}
keyExtractor={({id}, index) => id}
/>
You can build a component that takes your fields as its props, containing multiple Texts and an Image using your uri as the source. Style this like you would any other component, and then pass that component into renderItem.
You can embed the component immediately to the renderItem like this if the flatlist item is not complicated ( has a lot of component )
<FlatList
data={this.state.dataSource}
renderItem={({item}) => {
<View>
<Image source={{uri: item.uri.image}}/>
<Text>{item.userName}</Text>
<Text>{item.name}</Text>
</View>
}}
keyExtractor={(i) => i.toString()}
/>