Flatlist Items flicker and then disappear - react-native

I have a Flatlist that is supposed to represent items.
Yesterday the Flatlist worked without problems, and today it started flashing heavily when rendering and when the screen is called up again, only the last item is displayed.
The data is pulled async in this screen via axios from an API
I then rebuilt the Flatlist to the minimum status, but the error remains.
<FlatList
data={packages}
horizontal
showsHorizontalScrollIndicator={false}
keyExtractor={(item) => item.id}
snapToInterval={packageCardWidth}
bounces={false}
decelerationRate={0}
renderItem={({ item, index }) => {
return (
<PackageCard
containerWidth={packageCardWidth}
{...item}
/>
);
}}
/>
The code for the rendered item
export default function PackageCard(props) {
return (
<View style={[tw.style('flex-1'), { width: props.containerWidth }]}>
<View
style={[
tw.style(
'bg-white rounded-lg shadow-md pb-4 m-3 overflow-hidden'
),
{},
]}
>
<Image
source={{
uri: 'https://images.unsplash.com/photo-1577705998148-6da4f3963bc8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80',
}}
style={tw.style('h-64 w-full mb-4')}
/>
<View style={tw.style('px-3 p-2')}>
<Text style={tw.style('text-xl font-semibold')}>
{props.name}
</Text>
</View>
</View>
</View>
);
}

Related

How to show an icon on last index of flat list

I'm trying to wrap my flat list and trying to show an Icon after last index of Flatlist. I had tried but it works fine on a single row. when we data goes to next row it would not work.
Here is my flat list code. Modal and Input both are my custom component.
const renderItem = ({item}) => {
return (
<TouchableOpacity style={[styles.tagPostContainer, styles.viewTagContainer]}>
<AppText
type={'input'}
label={`#${item}`}
color={colors.placeholder}
containerStyle={[styles.tagPostInactiveTxt, styles.BgAddedTag]}
/>
</TouchableOpacity>
);
};
return(
<>
<View style={{flexDirection:'row',justifyContent:'flex-start'}}>
<FlatList
data={tags}
renderItem={renderItem}
keyExtractor={keyExtractor}
contentContainerStyle={styles.TagFlatlist}
/>
<TouchableOpacity
style={styles.plusIconContainer}
onPress={() => setVisible(true)}>
<CreateBuildIconFocus height={13} width={13} />
</TouchableOpacity>
</View>
<Modal
visible={visible}
buttonLabel={'Done'}
containerWidth={width / 1.7}
onCancel={onCancel}
onSubmit={onClick}
containerHeight={Platform.OS === 'android' ? 200 : 200}>
<Input
placeholder={'Add Tags'}
autoFocus={true}
minWidth={120}
maxWidth={150}
value={tag}
onChangeText={text => setTag(text)}
/>
</Modal>
</>
)
FlatList styles:
TagFlatlist: {
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
},
Here is my design screen.
I find a solution for this. You can implement ListFooterComponent that used for showing something on end of flatlist. Here you can see more details of ListFooterComponent.
Here are the code of Flatlist.
return(
<FlatList
data={tags}
renderItem={renderItem}
keyExtractor={keyExtractor}
ListFooterComponent={
<TouchableOpacity
style={styles.plusIconContainer}
onPress={() => setVisible(true)}>
<CreateBuildIconFocus height={13} width={13} />
</TouchableOpacity>
}
contentContainerStyle={styles.TagFlatlist}
/>
)

FlatList not rendering it showing anything other than FlatList

I was trying to render a list but it is not rendering if I try to render a text or an image it is rendering but the FlatList is not rendering this is the code that I have written
**
return(
<SafeAreaView forceInset={{ top: 'always' }} >
<Image
style={styles.tinyLogo}
source={require('../../assets/img.png')}
/>
<Text> checking </Text>
<FlatList
data={menu}
renderItem={(item) => {
return <Text>{item.name}</Text>
}}
keyExtractor={(item) => item.key }
/>
</SafeAreaView>
**
Update your renderItem to this
renderItem={({item}) => {
return <Text>{item.name}</Text>
}}

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.

React-Native horizontal FlatList

I have flat list that is returning a JSON feed with nested objects / arrays. All is working except horizontal listing, it still lists each item vertically. Does anyone know how I can list the returned images horizontally instead of vertically?
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={[data]}
horizontal={true}
keyExtractor={({ id }, index) => id}
renderItem= {({ item, index }) => (
<View>
{item.items.map((v, i) => (
<TouchableOpacity onPress={() => props.navigation.navigate('Pdp', {articleid: item.id})}>
<View style={styles.container}>
<Image style={styles.imgyoutubeprev} source={{ uri: chkValue(v.snippet.thumbnails.high.url) }} />
<Image style={styles.imgyoutubebtnoverlay} source={require('../assets/youtubebtn.png')} />
</View>
</TouchableOpacity>
))}
</View>
)}
/>
)}
We would need to have a bit more information about the styles that you are using. If the items are rendered vertically instead of horizontal then this is likely caused by the element that surrounds the FlatList.
Make sure that the View or other component that contains the FlatList has the flex: 1 style or at least takes up the full width. Otherwise the horizontal elements would still wrap and be rendered vertically.
Bonus tip: You might be able to remove the View child from the TouchableOpacity by moving the styles.container to the TouchableOpacity and then replacing the inner View with a Fragment.
Thanks all. The big difference was removing the view surrounding the item.items.map. I haven't had to force flex: 1 against the view, though I have forced flex 1 across the whole screen, so possibly thats helped as well. Thanks again all.
The code I used (taking on your code reduction, and is working as expected is;
return (
<View>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={[data]}
horizontal={true}
horizontal
keyExtractor={({ id }, index) => id}
renderItem= {({ item, index }) => (
item.items.map((v, i) => (
<TouchableOpacity onPress={() => props.navigation.navigate('Pdp', {articleid: item.id})}>
<Image style={styles.imgyoutubeprev} source={{ uri: chkValue(v.snippet.thumbnails.high.url) }} />
<Image style={styles.imgyoutubebtnoverlay} source={require('../assets/youtubebtn.png')} />
</TouchableOpacity>
))
)}
/>
)}
</View>
);
};

React Native Elements Handle ListItem click

I use React Native Elements library to create list items inside of a Flat List. I show a list of users and i need to handle style after a click.
My code is :
<View style={{flex: 1}}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<ListItem
leftAvatar={{source: {uri: item.avatar}}}
title={`${item.firstName} ${item.lastName}`}
// subtitle={item.email}
chevron
onPress={this.onItemClickHandler}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
<Button
title='Suivant'
onPress={() => navigation.navigate('LastStepToShare')}
containerStyle={{marginBottom: 15}}
/>
</View>
How can i edit the background of a clicked ListItem item ?
You could do something like this:
<FlatList
data={this.state.data}
renderItem={({item, index}) => {
const {selectedIndex} = this.state;
const itemStyle = selectedIndex === index ? styles.selected : styles.notSelected;
return (
<ListItem
leftAvatar={{source: {uri: item.avatar}}}
title={`${item.firstName} ${item.lastName}`}
style={itemStyle}
// subtitle={item.email}
chevron
onPress={() => this.onItemClickHandler(index)}
/>
)
}}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
and in your onItemClickHandler function, set the selectedIndex value in the state using this.setState.
Basically, get the selected index thanks to the onPress event and compare it to the current index from the renderItem function. Based on that, you can set a style variable.
Here is a sample code snippet, this might help you :
<FlatList
data={this.getAllTask()}
renderItem={({ item, index }) =>
<TouchableHighlight
onPress={() => {this.props.navigation.navigate('OtherPage', {text: item.task_name, index: index})}}>
<View style={styles.customRowContainer}>
<View style={styles.listContainer}>
<Image source={require('../Img/ic_task_icon.png')} style={styles.photo} />
<View style={styles.container_text}>
<Text style={styles.title}>
{item.task_name}
</Text>
<Text style={styles.description}>
ETA : {item.task_eta}
</Text>
</View>
</View>
</View>
</TouchableHighlight>}
keyExtractor={item => item.id}
/>
If you need to change the background color only while the item is pressed (ie. change back when the finger is up), you can customise underlayColor and activeOpacity of the underlying TouchableHighlight to achieve what you need:
<ListItem underlayColor="#ff0000" activeOpacity={1} title="Title" onPress={yourClickHandler} />
You can easily store the state of active Item, and set state on onItemClickHandler function, now you can change style according to state of item (is it active or not)
<View style={{ flex: 1 }}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
style={this.state.active === item.id ? styles.active : null} //***
leftAvatar={{ source: { uri: item.avatar } }}
title={`${item.firstName} ${item.lastName}`}
// subtitle={item.email}
chevron
onPress={() => this.onItemClickHandler(item.id)}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
<Button
title='Suivant'
onPress={() => navigation.navigate('LastStepToShare')}
containerStyle={{ marginBottom: 15 }}
/>
</View>
and
this.onItemClickHandler(id) => {
this.setState({
active: id
})
}