Why SectionList onEndReached is not working? - react-native

When I load my component onEndReached will be triggered one time before I scroll my <SectionList />, but when I scroll to bottom onEndReached won't be triggered any more.
Here is my code:
render (
return (
<View style={{ flex: 1 }}>
<SectionList
style={{ backgroundColor: 'pink' }}
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={() => console.log('refreshControl')}
tintColor='gray'
/>
}
renderSectionHeader={this.sectionHeader}
renderItem={this.renderSectionView}
sections={reservations}
onEndReachedThreshold={0.05}
onEndReached={(data) => {
console.log('data', data); // { distanceFromEnd: -457 }
console.log('onEndReached');
}}
keyExtractor={(item, index) => index}
ItemSeparatorComponent={() => <View style={{ backgroundColor: 'gray', height: StyleSheet.hairlineWidth }} />}
/>
</View>
);
);
Here is my <SectionList /> screen:
In my <SectionList /> refreshControl is fine but onEndReached is not working, any one knows what happened ? Thanks.

Looks like a lot of people are experiencing the same. There is a suggestion to change the onEndReachedThreshold to value bigger that 0.05, for example: 0.5

Try something like
render (
return (
<SafeAreaView style={{ flex: 1 }}>
<SectionList
style={{ backgroundColor: 'pink' }}
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={() => console.log('refreshControl')}
tintColor='gray'
/>
}
renderSectionHeader={this.sectionHeader}
renderItem={this.renderSectionView}
sections={reservations}
onEndReachedThreshold={0.05}
onEndReached={(data) => {
console.log('data', data); // { distanceFromEnd: -457 }
console.log('onEndReached');
}}
keyExtractor={(item, index) => index}
ItemSeparatorComponent={() => <View style={{ backgroundColor: 'gray', height: StyleSheet.hairlineWidth }} />}
/>
</SafeAreaView>
);
);

Related

How to add text title with react native FlatGride?

Using the below code I can return FlatGrid according to my item list.
return (
<FlatGrid
itemDimension={130}
data={items}
style={styles.gridView}
// staticDimension={300}
// fixed
spacing={10}
renderItem={({ item }) => (
<ImageBackground source={ item.source} style={[styles.itemContainer, ]}>
<Text style={styles.itemName}>{item.name}</Text>
</ImageBackground>
)}
/>
);
But I want to add some text before the FlatGrid. So I update my code like below.
return (
<View>
<Text style={{color:'#000000'}}>This is the text</Text>
<FlatGrid
itemDimension={130}
data={items}
style={styles.gridView}
spacing={10}
renderItem={({ item }) => (
<ImageBackground source={ item.source} style={[styles.itemContainer, ]}>
<Text style={styles.itemName}>{item.name}</Text>
</ImageBackground>
)}
/>
</View>
);
But as the above code output, I can see only the text. ("This is the text").
I am new to react-native. Can anyone say how I fix this issue?
Try for SectionGrid
It will give you the title & list as well is same component
<SectionGrid
itemDimension={130}
sections={[
{
title: 'Numbers',
data: [1,2,3,4,5,6],
},
{
title: 'Alphabets',
data: ['A', 'B', 'C', 'D', 'E'],
},
]}
renderItem={({ item }) => (<Text>{item}</Text>)}
renderSectionHeader={({ section }) => (
<Text style={{ fontSize: 20 }}>{section.title}</Text>
)}
/>
This worked for me. Used different screen parts for each component.
return (
<View style={{flexDirection: "column",flex: 1, }}>
<View style={{ flex: 1,backgroundColor:'red' }}>
<Text style={{textAlign:'center',fontSize:20}}>This istext</Text>
</View>
<View style={{ flex: 10,backgroundColor:'blue'}}>
<FlatGrid
itemDimension={130}
data={items}
style={styles.gridView}
spacing={10}
renderItem={({ item }) => (
<ImageBackground source={ item.source} style={[styles.itemContainer, ]}>
<Text style={styles.itemName}>{item.name}</Text>
</ImageBackground>
)}/>
</View>
</View>
);

FlatList can't scroll horizontally

I'm trying to scroll horizontal but Its never move to the second or third item.
When I'm dragging left I cant see part of the second elements.
export const Flat: React.FC = () => {
const aaa = [{}, {}, {}]
const renderItem = ({item, index}: any) => {
if(index === 0){
return <View style={{width:"100%", backgroundColor: "green"}}>
<Text> asdasad </Text>
</View>
}
else if(index === 1){
return <View style={{width: "100%", backgroundColor: "red"}}>
<Text> asdasad </Text>
</View>
}
return <View style={{width: "100%", backgroundColor: "blue"}}>
<Text> asdasad </Text>
</View>
}
return <View style={{flex: 1}}>
<FlatList style={{flex: 1}}
contentContainerStyle={{ flex: 1}}
horizontal={true}
data={aaa}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
pagingEnabled={true}
// bounces={false}
/>
</View>
}
Here is - https://snack.expo.dev/RNeBkS7Rk , I just added <ScrollView horizontal> and change yours styles : width:"100%" to width:300

Two flatlist in one Reat Native

I'm planning to achieve this in mobile. Using Flatlist.
It scrolls as a whole
Im trying to create this in react native and my code looks like this
<Content nestedScrollEnabled
style={{ flex: 1, backgroundColor: COLOR.LIGHT }}
contentContainerStyle={{ flex: 1 }} // important!
>
<List>
{!_.isEmpty(this.state.newNotif) ?
<React.Fragment>
<ListItem itemDivider>
<Text style={{ color: '#333333', fontSize: 16 }}>New</Text>
</ListItem>
<FlatList
ref="infiniteList"
data={this.state.newNotif}
keyExtractor={(x, i) => x.id.toString()}
renderItem={(data) => this.renderNewNotifCard(data.index, data.item)}
// onEndReached={({ distanceFromEnd }) => {
// console.log(distanceFromEnd);
// this.handleEnd()
// }}
// onEndReachedThreshold={0.5}
/>
</React.Fragment>
:
null
}
{!_.isEmpty(this.state.earlierNotif) ?
<React.Fragment>
<ListItem itemDivider>
<Text style={{ color: '#333333', fontSize: 16 }}>Earlier</Text>
</ListItem>
<FlatList
data={this.state.earlierNotif}
// onEndReached={() => this.reachedEndCallBack()}
keyExtractor={(x, i) => x.id.toString()}
onEndReached={({ distanceFromEnd }) => {
console.log(distanceFromEnd);
this.handleEnd()
}}
onEndReachedThreshold={0.5}
renderItem={(data) => this.renderEarlierNotif(data.index, data.item)}
/>
</React.Fragment>
:
null
}
</List>
But seems its not having scroll as a whole, It scroll of each set of flatlist.
I hope some could help me.
You should use SectionList with section header - https://reactnative.dev/docs/sectionlist

react-native: flatlist with dynamic numColumns depending json params

This is my json:
{
data:[
{id:1,type:0...},{id:2,type:0...},{id:3,type:1...},
]
}
and Flatlist
_keyExtractor = (item,index) => item.id.toString();
<FlatList
data={this.state.products}
renderItem={this.renderItem}
keyExtractor={this._keyExtractor}
numColumns={3}
/>
I want something like this:
numColumns={item.type ? 1 : 2}
Is it possible?
Unfortunately, numColumns sets the number of columns for the global FlatList, but it is possible to create a similar behavior in your renderItem function.
Of course it is possible that you have to modify the structure of your data beforehand, so that this workaround is applicable for you.
See example below:
Data:
this.state={
data:[
{id:1,type:0},{id:2,type:1},{id:3,type:1},
{id:4,type:0},{id:5,type:1},{id:6,type:0},
]
}
Render:
const WIDTH = Dimensions.get('window').width; // get the screen width
renderItem({item}){
// if type == 0, render two views side by side
if (item.type == 0){
return(
<View style={{width: WIDTH, flexDirection: 'row'}}>
<View style={{ backgroundColor: 'red', width: WIDTH/2 }}>
<Text> {item.id} a) </Text>
</View>
<View style={{ backgroundColor: 'blue', width: WIDTH/2 }}>
<Text> {item.id} b) </Text>
</View>
</View>
);
}else{
// otherwise render only one item
return (
<View style={{ backgroundColor: 'green', width: WIDTH }}>
<Text> {item.id} </Text>
</View>
);
}
}
render() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.data}
keyExtractor={(item) => item.id.toString()}
renderItem={(item) => this.renderItem(item)}
/>
</SafeAreaView>
);
}
Image:

Styling react native components

When I run following code on my phone
render() {
return [
<View style={{ flex: 1, flexDirection: 'row' }}>
<Search />
</View>,
<View style={{ flex: 1, flexDirection: 'row' }}>
<FlatList
style={styles.list}
data={this.state.products}
renderItem={({ item }) => <ProductCard product={item} />}
keyExtractor={item => item.id}
/>
</View>,
];
}
I am getting screen split between Search and Productcard component. It feels like each one of them takes by default 50% of screen, but I want them to come one after each other.
Search component is just a dummy text:
export default function Search() {
return <Text>Hej</Text>;
}
But when I remove around them it looks good.
are you looking for something like this?
render() {
return(
<View style={{flex: 1, flexDirection: 'column'}}>
<View style={{flexDirection: 'row' }}>
<Search />
</View>,
<View style={{ flex: 1, flexDirection: 'row' }}>
<FlatList
style={styles.list}
data={this.state.products}
renderItem={({ item }) => <ProductCard product={item} />}
keyExtractor={item => item.id}
/>
</View>
</View>
);
}
I suppose you want to make them scroll, if so you have to wrap them around a <ScrollView>.
like so,
render() {
return (
<ScrollView>
<View style={{ flex: 1, flexDirection: 'row' }}>
<Search />
</View>,
<View style={{ flex: 1, flexDirection: 'row' }}>
<FlatList
style={styles.list}
data={this.state.products}
renderItem={({ item }) => <ProductCard product={item} />}
keyExtractor={item => item.id}
/>
</View>
</ScrollView>
);
}
And in second case if you want only the second half to be scrollable just wrap that view inside a <ScrollView> tag.
Thx for helping, it got me in right direction but I got it working by code below:
<View>
<Search />,
<FlatList
style={styles.list}
data={this.state.products}
renderItem={({ item }) => <ProductCard product={item} />}
keyExtractor={item => item.id}
/>
,
</View>