react-native-web
react-native-web copied to clipboard
scrollToIndex and scrollToLocation not working on FlatList, SectionList
scrollToIndex and scrollToLocation not working on FlatList, SectionList
Sample code: (url) https://snack.expo.io/I9cYUYxJi
Environment (include versions). Did this work in previous versions?
- "react": "16.13.1",
- "react-dom": "^17.0.1",
- "react-native": "0.63.3",
- "react-native-web": "^0.14.9",
- "expo": "^39.0.5",
- Browser: Chrome, Safari
Same issue with electron :
My dependencies :
"react-native-web": "^0.14.11",
"electron": "^6.0.12",
"expo": "^40.0.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-native": "^0.63.4",
A work around I did is to define the function getItemLayout
,
Example on expo: https://snack.expo.io/@gusgard/react-native-swiper-flatlist
Code: https://github.com/gusgard/react-native-swiper-flatlist/blob/master/src/components/SwiperFlatList/SwiperFlatList.tsx#L236
For some reason adding a delay of even 1 ms to the scrollToIndex
call solved the issue for me on web.
I.e.
//...
setTimeout(()=>{
flatListRef.current.scrollToIndex({index: 0});
}, 1);
//...
add height to the container should fix the problem container: { flex: 1, paddingTop: 10, height: 200 },
In my case, (horizontal flatlist on web), I needed to add width for Flatlist component, it worked even without getItemLayout
const ITEM_WIDTH = 550;
const swiperRef = useRef(null);
const onViewChanged = React.useRef(({ viewableItems }) => {
if (viewableItems.length > 0) {
const { index, item } = viewableItems[0];
setActivePhotoIndex(index);
}
});
const viewConfigRef = React.useRef({ viewAreaCoveragePercentThreshold: 100 });
<FlatList
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
marginHorizontal: 10,
}}
**style={{ width: ITEM_WIDTH}}**
snapToInterval={ITEM_WIDTH}
decelerationRate={0}
overScrollMode={"never"}
snapToAlignment={"center"}
horizontal
ref={swiperRef}
data={data}
// getItemLayout={(data, index) => { return {length: ITEM_WIDTH, index, offset: ITEM_WIDTH * index} }}
// onScrollEndDrag={() => console.log('Scroll end')}
viewabilityConfig={viewConfigRef.current}
onViewableItemsChanged={onViewChanged.current}
renderItem={({ item, index }) => {
return (
<View
style={{
width: ITEM_WIDTH,
alignItems: "center",
}}
>
Here, you can see that, without a height set, the scroll is completely broken in the web implementation. The list doesn't shrink to what is actually shown, and other batches of items don't load.
就我而言,(网络上的水平平面列表),我需要为 Flatlist 组件添加宽度,即使没有 getItemLayout 它也能工作
const ITEM_WIDTH = 550; const swiperRef = useRef(null); const onViewChanged = React.useRef(({ viewableItems }) => { if (viewableItems.length > 0) { const { index, item } = viewableItems[0]; setActivePhotoIndex(index); } }); const viewConfigRef = React.useRef({ viewAreaCoveragePercentThreshold: 100 }); <FlatList showsHorizontalScrollIndicator={false} contentContainerStyle={{ marginHorizontal: 10, }} **style={{ width: ITEM_WIDTH}}** snapToInterval={ITEM_WIDTH} decelerationRate={0} overScrollMode={"never"} snapToAlignment={"center"} horizontal ref={swiperRef} data={data} // getItemLayout={(data, index) => { return {length: ITEM_WIDTH, index, offset: ITEM_WIDTH * index} }} // onScrollEndDrag={() => console.log('Scroll end')} viewabilityConfig={viewConfigRef.current} onViewableItemsChanged={onViewChanged.current} renderItem={({ item, index }) => { return ( <View style={{ width: ITEM_WIDTH, alignItems: "center", }} >
Thank you so much it works for me
A work around I did is to define the function
getItemLayout
,Example on expo: https://snack.expo.io/@gusgard/react-native-swiper-flatlist
Code: https://github.com/gusgard/react-native-swiper-flatlist/blob/master/src/components/SwiperFlatList/SwiperFlatList.tsx#L236
getItemLayout={(__data, ItemIndex: number) => ({
length: Dimensions.get('window').height,
offset: Dimensions.get('window').height * ItemIndex,
index: ItemIndex,
})}
thanks, it works to me
Hi, to solve this issue, I've:
- implemented the
getItemLayout
function using theheight
of therenderItem
aslength
. - added
height
to the container style of theFlatList
.
For example, using a renderItem
height of 350
:
getItemLayout={(data, index) => ({
length: 350,
offset: 350 * index,
index,
})}
In my code, there's no need to use width
in the style
of the FlatList
.
I've used listRef.current?.scrollToIndex({ index })
to update the scroll index and it worked...finally 🥇