Infinite Scrolling is not working properly in react native flatList

1.2k Views Asked by At

I am trying to create carousel with infinite scrolling by appending same array, in onViewableItemsChanged i update state on second last index so i can get updated data but list only update once i think i have error in onViewableItemsChanged so please tell me where am i wrong ?

This is my flatListSldier file where i am doing major work.

import {
  View,
  Text,
  StyleSheet,
  FlatList,
  Dimensions,
  UIManager,
  LayoutAnimation,
} from 'react-native';
import React, {useRef, useState, useEffect} from 'react';
import Indicator from './Indicator';
import Child from './Child';

const FlatListSlider = props => {
  let sliderTimer;

  const [listData, setListData] = useState({
    index: 0,
    data: props.data,
  });

  const slider = useRef();

  const state = {
    data: [],
    imageKey: 'image',
    local: false,
    width: Math.round(Dimensions.get('window').width),
    height: 230,
    separatorWidth: 0,
    loop: true,
    indicator: true,
    indicatorStyle: {},
    indicatorContainerStyle: {},
    indicatorActiveColor: '#3498db',
    indicatorInActiveColor: '#bdc3c7',
    indicatorActiveWidth: 6,
    animation: true,
    autoscroll: true,
    timer: 3000,
    onPress: {},
    contentContainerStyle: {},
  };
  if (Platform.OS === 'android') {
    if (UIManager.setLayoutAnimationEnabledExperimental) {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }
  }

  const viewabilityConfig = useRef({
    viewAreaCoveragePercentThreshold: 50,
  });

  const onViewableItemsChanged = useRef(({viewableItems, changed}) => {
    console.log('viewableItems', viewableItems);
    if (viewableItems.length > 0) {
      let currentIndex = viewableItems[0].index;
      if (
        currentIndex % props.data.length === props.data.length - 1 &&
        props.loop
      ) {
        setListData({
          index: currentIndex,
          data: [...listData.data, props.data],
        });
      } else {
        setListData({...listData, index: currentIndex});
      }
    }
  });

  useEffect(() => {
    console.log('stateData.data', listData.data.length);
  }, [listData.data]);

  const itemWidth = props.width;
  const separatorWidth = state.separatorWidth;
  let totalItemWidth = itemWidth + separatorWidth;

  return (
    <View>
      <FlatList
        ref={slider}
        horizontal={true}
        pagingEnabled={true}
        snapToInterval={totalItemWidth}
        decelerationRate="fast"
        bounces={false}
        data={listData.data}
        showsHorizontalScrollIndicator={false}
        renderItem={({item, index}) => {
          return (
            <Child
              style={{width: props.width}}
              item={item}
              imageKey={props.imageKey}
              onPress={props.onPress}
              index={listData.index % props.data.length}
              active={index === listData.index}
              local={props.local}
              height={state.height}
            />
          );
        }}
        ItemSeparatorComponent={() => (
          <View style={{width: props.separatorWidth}} />
        )}
        keyExtractor={(item, index) => item.toString() + index}
        onViewableItemsChanged={onViewableItemsChanged.current}
        viewabilityConfig={viewabilityConfig.current}
        getItemLayout={(data, index) => ({
          length: totalItemWidth,
          offset: totalItemWidth * index,
          index,
        })}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  image: {
    height: 230,
    resizeMode: 'stretch',
  },
  indicatorContainerStyle: {
    marginTop: 18,
  },
  shadow: {
    ...Platform.select({
      ios: {
        shadowColor: 'black',
        shadowOffset: {width: 3, height: 3},
        shadowOpacity: 0.4,
        shadowRadius: 10,
      },
      android: {
        elevation: 5,
      },
    }),
  },
});

export default FlatListSlider;
0

There are 0 best solutions below