skip to Main Content

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

2

Answers


  1. 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)
      }, []);
    
    Login or Signup to reply.
  2. 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 });
                });
              }}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search