scrolltolocation not working outside of initialNumToRender props window in Sectionlist untill I manually scroll - react-native

I am using sectionlist for showing data in react native.
I have large data with a section list.
Here We use scrolltolocation for scrolling to the specific section but it is not working until I render to that section using manual scroll
My Code:
<SectionList
sections={this.props.fooddata}
ref={(s) => (this.sectionList = s)}
//onScroll={this.handleScroll}
stickySectionHeadersEnabled={true}
onViewableItemsChanged={this.props.onCheckViewableItems}
viewabilityConfig={{
itemVisiblePercentThreshold: 50 //means if 50% of the item is visible
}}
removeClippedSubviews={false}
maxToRenderPerBatch={6}
scrollEnabled={true}
onScrollToIndexFailed={info => {
const wait = new Promise(resolve => setTimeout(resolve, 500));
wait.then(() => {
//flatList.current?.scrollToIndex({ index: info.index, animated: false });
});
}}
initialNumToRender={4}
windowSize={5}
ListFooterComponent={this.ItemSeprator}
style={{ width: this.windowwidth,top:this.props.searchclicked?135:(this.props.nonveg || this.props.veg)?200:117,bottom:0,position:'absolute'}}
// keyExtractor={(item, index) => index}
keyExtractor={this.keyExtractor}
renderSectionHeader={({ section,index }) => this.createSection(section,index)}
// renderItem={(item)=>this.jackRecommned(item)} //{({ item, index }) => this.renderItem(item, index)}
renderItem={this.renderItem.bind(this)}
renderFooter={this.footer}
/>

Related

How can I get visible item index from scrolling position from FlatList in React-Native?

I have a horizontal FlatList where I render a collection, now I want to know which item is into view (index) taking into account that each item width is almost equal to device width, lets say 400, how can I get visible item index on my onScroll method?
<FlatList scrollEventThrottle={16} onScroll={handleScroll} showsHorizontalScrollIndicator={false} style={{ width:'100%', '}}
horizontal={true} data={categories} keyExtractor={item => item.toString()}
renderItem={({ item, index }) =>
<TouchableOpacity style={{ width:400,height:275 }}>{ item }</Text>
</TouchableOpacity>}
/>
handleScroll method:
const handleScroll = (event) => {
console.log(event.nativeEvent.contentOffset.x);
};
You can use FlatList onViewableItemsChanged prop to get what you want.
const _onViewableItemsChanged = React.useCallback(({ viewableItems, changed }) => {
console.log("Visible items are", viewableItems);
console.log("Changed in this iteration, ", changed);
}, []);
const _viewabilityConfig = {
itemVisiblePercentThreshold: 60
}
<FlatList
scrollEventThrottle={16}
showsHorizontalScrollIndicator={false}
style={{ width: '100%' }}
horizontal={true}
data={categories}
onViewableItemsChanged={_onViewableItemsChanged}
viewabilityConfig={_viewabilityConfig}
keyExtractor={item => item.toString()}
renderItem={({ item, index }) =>
<TouchableOpacity style={{ width: 400, height: 275 }}><Text>{item}</Text>
</TouchableOpacity>}
/>
viewabilityConfig can help you to make whatever you want with viewability settings. In code example 60 means that item is considered visible if it is visible for more than 60 percents.

react native flatlist jumps items periodically until reaches specific item

I'm using Flatlist and list items don't have specific height, when I want to scroll to a specific index it's not scrolling to an exact item, and takes a while to go to that item.
this is the video of the problem
when I use this.flatlist.scrollToindex(), I get the error flatlist.scrollToindex() is not a function so I use :
this.flatList.scrollToItem({
animated: true,
item: item,
viewPosition: 0.5,
});
this is the component which has a flatlist inside and doesn't have getItemLayout function:
<CustomFlatList
header={headerComponent}
inverted={renderAsChat || invertedList}
style={[
postStyles.dashboardContainer,
isLonelyPost && { backgroundColor: '#fff' },
]}
loading={loading}
onRefresh={customRefresh === true ? refresh : this.onRefresh}
content={content}
pageTabTitle={pageTabTitle}
renderItem={({ item, key, index }) =>
this.renderPostItem(item, index, pageTabTitle)
}
emptyMessage={emptyMessage}
keyExtractor={(item, key) => this.getItemKey(item)}
loadMore={customLoadMore === true ? loadMore : this.loadMore}
scrollState={this.state.sendPostButtonVisible}
changeScrollState={this.changeScrollState}
navigation={navigation}
onViewableItemsChanged={this.onVideoExitScreen}
enableLoadMore={enableLoadMore && !isLonelyPost}
yOffsetThreshold={1000}
ref={(ref) => { this.flatList = ref; }}
/> : <View />

Flatlist freezes when `onEndReached` is triggered

I'm using react native and I have a flatlist that can render anywhere from 2 items to over 2000. Due to this, it's really important to optimize the performance to make sure the Flatlist doesn't lag. I've tried to optimize performance with the props provided in the docs. However, I noticed when I scroll down to the bottom and my loadMoreData function is called, scrolling freezes for like 1 second. How can I make it so this doesn't happen? Thank you.
Code:
const [data, setData] = React.useState(mockData);
// Load more data
const loadMoreData = () => {
setData((prevItems) => {
return [...new Set([...prevItems, ...testItem])]; // 'testItem' is an array with one object that
});
};
return (
<FlatList
extraData={data}
data={data}
getItemLayout={(data, index) => ({
length: 78,
offset: 78 * index,
index,
})}
initialNumToRender={7}
maxToRenderPerBatch={10}
windowSize={10}
onEndReached={loadMoreData} // freezes when this is called
onEndReachedThreshold={0.1}
removeClippedSubviews={true}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<>
<Swipeable renderRightActions={(progress, dragX) =>}>
<HoldItem items={InventoryHoldMenuItems}>
<Layout>
<InventoryItem item={item} />
</Layout>
</HoldItem>
</Swipeable>
</>
)}
/>
)}
)

React-Native : calculating the scrollToItem of a FlatList with a ref on componentDidMount and rendering it

I have a FlatList which renders numbers from 1-10 along with a radio button. If I have pre-selected number which could be dynamic, that numbered radio button is pre-selected. How to calculate the scrollToItem/scrollToIndex in this case ?
componentDidMount() {
this.scrollToItem();
}
scrollToItem = () => {
let dynamicIndex = dynamicIndex
//calcuate the dynamic Index
this.flatListRef.scrollToIndex({ animated: true, index: dynamicIndex });
};
<FlatList
ref={ref => {this.flatListRef = ref;}}
bounces={false}
keyExtractor={item => item.id}
data={listData}
renderItem={({ item, index })=>
this.renderItem(item,index)}
/>
But it throws error "Cannot read property 'scrollToIndex' of index. Basically it can't find 'this.flatListRef' during component mount.

numColumns breaks scrollToIndex react native FlatList

I'm using react native's FlatList to display a list of items, and also check which items are currently viewable. In my items there's one item which is marked mostUsed if the item is not viewable I display a link at the top, the user can click that and scroll to that item, using scrollToIndex. scrollToIndex works well without setting numColumns, when I set numColumns={2} I get scrollToIndex out of range: 9 vs 4 error.
setScrollIndex = () => {
if (this.state.scrollIndex !== 0) {
return;
}
for (let i = 0; i < this.state.items.length; i++) {
const items = this.state.items;
if (items[i] && items[i].mostUsed) {
this.setState({
scrollIndex: i,
});
}
}
};
// scroll to index function
scrollToIndex = () => {
this.flatListRef.scrollToIndex({
animated: true,
index: this.state.scrollIndex,
});
};
<FlatList
data={this.state.items}
numColumns={2}
keyExtractor={(item, index) => index.toString()}
ref={ref => {
this.flatListRef = ref;
}}
showsVerticalScrollIndicator={false}
onViewableItemsChanged={this.handleViewableItemsChanged}
viewabilityConfig={this.viewabilityConfig}
renderItem={({ item, index }) => (
<Card
title={item.title}
description={item.description}
mostUsed={item.mostUsed}
style={{ width: item.width }}
/>
)}
/>
expo snack
Looks like FlatList's scrollToIndex changes the way it views index if numColumns is higher then 1.
It may be more correct to call it scrollToRowIndex since it does not work on item index in case of multiple columns.
For your case this worked for me on expo:
scrollToIndex = () => {
this.flatListRef.scrollToIndex({
animated: true,
index: Math.floor(this.state.scrollIndex / numColumns),
});
};