Reputation: 97
I'm trying to create an auto scroll flatlist carousel that can also allow the user to scroll manually. The problem is that I get this error flatListRef.scrollToIndex is not a function
. I tried searching how other people create an auto scroll flatlist but their solution is using class.
const flatListRef = useRef(null)
useEffect (() => {
const totalIndex = data.length - 1;
setInterval (() => {
if(flatListRef.current.index < totalIndex) {
flatListRef.scrollToIndex({animated: true, index: flatListRef.current.index + 1})
} else {
flatListRef.scrollToIndex({animated: true, index: 0})
}
}, 3000)
}, []);
const renderItem = ({item}) => {
return (
<View style={styles.cardView}>
<Image style={styles.image} source={item.image} resizeMode="contain"/>
</View>
)
}
return (
<View style={{paddingHorizontal: 10}} >
<FlatList
ref={flatListRef}
data={data}
keyExtractor={data => data.id}
horizontal
pagingEnabled
scrollEnabled
snapToAlignment="center"
scrollEventThrottle={16}
decelerationRate={"fast"}
showsHorizontalScrollIndicator={true}
persistentScrollbar={true}
renderItem={renderItem}
/>
</View>
);
styles:
cardView: {
flex: 1,
width: width - 20,
height: height * 0.21,
backgroundColor: Colors.empty,
alignItems: 'center',
justifyContent: 'center',
},
image: {
backgroundColor: Colors.empty,
width: width - 20,
height: height * 0.21,
},
Upvotes: 1
Views: 3700
Reputation: 187
Just use scrollToEnd()
method in useEffect with a useRef on the Flatlist.
Example :
const flatListRef = useRef(null);
const data = ['Message 1', 'Message 2', 'Message 3']; // Dummies datas
useEffect(() => {
// Scroll to the bottom when data change
flatListRef.current.scrollToEnd({ animated: true });
}, [data]);
return (
<View style={{ flex: 1 }}>
<FlatList
ref={flatListRef}
data={data}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
onContentSizeChange={() => flatListRef.current.scrollToEnd({ animated: true })}
/>
</View>
);
};
Upvotes: 0
Reputation: 176
as per the guide on React Native onScrollToIndexFailed
you have to override
onScroll={(e) => {
this.setState({ currentIndex: Math.floor(e.nativeEvent.contentOffset.x / (dimensions.wp(this.props.widthPercent || 100) - 1)) });
}}
onScrollToIndexFailed={info => {
const wait = new Promise(resolve => setTimeout(resolve, 500));
wait.then(() => {
flatListRef?.current?.scrollToIndex({ index: 0, animated: true });
});
}}
Upvotes: 0
Reputation: 1307
useRef returns a mutable object whose .current property is initialized to initial value. So basically you need to access scrollIndex like this
flatListRef.current.scrollToIndex({animated: true, index: flatListRef.current.index + 1})
Edit: To answer your comment, you should've asked directly for auto-scrolling, however, The code below should work!
const flatListRef = useRef(null)
let index=0;
const totalIndex = datas.length - 1;
useEffect (() => {
setInterval (() => {
index++;
if(index < totalIndex) {
flatListRef.current.scrollToIndex({animated: true, index: index})
} else {
flatListRef.current.scrollToIndex({animated: true, index: 0})
}
}, 1000)
}, []);
Upvotes: 2