React-Native FlatList issues in RTL view - react-native

I have a Horizontal FlatList and in RTL view the FlatList just constantly call onEndReached method but that's not the case in LTR view.
It's a big issue that's not solved https://github.com/facebook/react-native/issues/19979
Did anyone try to find a workaround for this issue ?
Here is my implementation:
<FlatList
horizontal
directionalLockEnabled
data={recommendedPosts}
onRefresh={handleRefresh}
refreshing={isRefreshing}
onEndReachedThreshold={0.5}
onEndReached={onEndReached}
keyExtractor={(item) => item?._id}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
ListHeaderComponentStyle={styles.footerStyle}
ListFooterComponentStyle={styles.footerStyle}
renderItem={({ item, index }) => (
<AdGridCard
ad={item}
containerStyle={styles.recommendedCard}
onPress={() => goToDetails(item?._id, index)}
/>
)}
contentContainerStyle={styles.contentContainerStyle}
getItemLayout={(d, index) => {
return { length: hp(250), offset: index * hp(250), index };
}}
ListFooterComponent={<LoadingComponent isLoading={loading} />}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>

Related

How to get current active index of FlatList in Reract Native?

I have below simple FlatList:
<FlatList
data={Images}
renderItem={({item}) => <Item item={item} />}
keyExtractor={item => item.index}
horizontal
showsHorizontalScrollIndicator={false}
pagingEnabled
onScroll={onScroll}
decelerationRate={-100000000000000}
scrollEventThrottle={16}
/>
How to get current active index of the FlatList as switching between different list item?
You can pass a callback to the onViewableItemsChanged prop to accomplish this.
const onViewableItemsChanged = ({ viewableItems, changed }) => {
console.log(viewableItems);
console.log(changed);
};
// ...
<FlatList
// ...
onViewableItemsChanged={onViewableItemsChanged}
/>
Docs here: https://reactnative.dev/docs/flatlist#onviewableitemschanged
Blog post with example: https://thewebdev.info/2022/02/19/how-to-get-the-index-of-the-currently-visible-item-in-a-react-native-flat-list/

Flastlist issue showing posts one by one

I'm using flatlist to show a feed of posts (like tiktok), the issue is that sometimes is showing up a part of the second post instead of scroll down to it. See the picture below:
That issue happens when I'm scrolling down faster.
Flatlist code:
<FlatList
showsVerticalScrollIndicator={false}
data={videos}
keyExtractor={(item, index) => index.toString()}
onEndReachedThreshold={3}
onEndReached={() => {
if (!isFetching) {
debouncedFetchMore();
}
}}
snapToInterval={PICTURE_HEIGHT}
disableIntervalMomentum
viewabilityConfig={viewabilityConfig}
onViewableItemsChanged={onViewableItemsChanged}
onRefresh={() => getPosts('video', FetchMode.REFRESH)}
refreshing={false}
//Optimization
renderItem={renderItem}
removeClippedSubviews
initialNumToRender={1}
maxToRenderPerBatch={2}
windowSize={2}
// Scrolling fixes
decelerationRate="fast"
snapToAlignment="start"
overScrollMode="never"
bounces
scrollEventThrottle={8}
getItemLayout={(_, index) => ({
length: PICTURE_HEIGHT,
offset: PICTURE_HEIGHT * index,
index,
})}
pagingEnabled
ref={refFlatList}
/>

How to fix error VirtualizedLists should never be nested inside plain ScrollViews with the same orientation?

My application has the error "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.", but I don't know how to solve it. In ScrollView I have two Flatlists and a header.
Screen: Flatlists inside my ScrollView
My code:
const renderItem = ({ item }) => <AssuntoCard item={item} />;
return (
<Container> // SCROLLVIEW
<TouchableOpacity
>
<Close />
</TouchableOpacity>
<Titulo>
<Bold>O que vocĂȘ deseja</Bold>
{"\n"}estudar hoje?
</Titulo>
<Subtitulo>Selecione um capĂ­tulo: </Subtitulo>
<Linhas> // View with two columns
<Colunas> // Column 1 for even items
<FlatList
scrollEnabled={false}
data={card.filter((item) => item.id % 2 == 0)}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</Colunas>
<Colunas> // Column 2 for odd items
<FlatList
scrollEnabled={false}
data={card.filter((item) => item.id % 2 !== 0)}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</Colunas>
</Linhas>
<Modal>
// ...
</Modal>
</Container>
);

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 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
})
}