Show different data based on the active carousel item

I have a horizontal <Animated.ScrollView>, a "carousel" in my React-native app that displays one item at the center of the screen and the edges of previous and next item. I want to show data (lessons) below the ScrollView. Can someone tell me or point to a resource about how can I know what item the screen is now displaying and then showing data based on that? Do I need to calculate the current item in the scrollview or pass it as an argument to some function?

My goal:

enter image description here

Parent component:

 return (
<View style={styles.screen}>
  <View style={styles.thumbnailScrollContainer}>
    <HorizontalContentScroll
      data={LESSONS_DATA}
    />
  </View>
  <View style={styles.dataScrollContainer}>
    <FlatList numColumns={2} data={lessonsByCategory} renderItem={renderLessonItem} />
  </View>
</View> );

And here my horizontal Scrollview

const HorizontalContentScroll = ({ data}: HorizontalContentProps) => {
  const { width, height } = Dimensions.get('window');
  const scrollX = useRef(new Animated.Value(0)).current;
  const ITEM_SIZE = width * 0.8;

  const getInterval = (offset: any) => {
    // console.log('offset', offset);
  };

  const scrollableData = (data as Array<ContentCategory>).map(
    (item: ContentCategory, index: number) => {
      const inputRange = [
        (index - 1) * ITEM_SIZE,
        index * ITEM_SIZE,
        (index + 1) * ITEM_SIZE,
      ];
      const translateY = scrollX.interpolate({
        inputRange,
        outputRange: [40, 10, 40],
        // extrapolate: 'clamp',
      });

      return (
        <Card
          size="large"
          style={{
            ...styles.titleCard,
            transform: [{ translateY }],
            width: ITEM_SIZE,
          }}
          key={`${item.category}-${index}`}
        >
          <Text>{item.category}</Text>
        </Card>
      );
    }
  );

  return (
    <Animated.ScrollView
      contentContainerStyle={styles.contentContainer}
      horizontal
      onScroll={Animated.event(
        [{ nativeEvent: { contentOffset: { x: scrollX } } }],
        {
          useNativeDriver: true,
          listener: (event) => {
            getInterval(event);
          },
        }
      )}
      scrollEventThrottle={16}
      showsHorizontalScrollIndicator={false}
      bounces={false}
      pagingEnabled
      snapToAlignment="center"
      snapToInterval={330}
      decelerationRate={'fast'}
    >
      {scrollableData}
    </Animated.ScrollView>
  );
};

export default HorizontalContentScroll;

I think I have to do something in this map function like pass the current item up to my parent component but how? If I try to call a function that sets the state in the parent I get an error of "Warning: Cannot update a component from inside the function body of a different component."

const scrollableData = (data as Array<ContentCategory>).map(
    (item: ContentCategory, index: number) => {
      const inputRange = [
        (index - 1) * ITEM_SIZE,
        index * ITEM_SIZE,
        (index + 1) * ITEM_SIZE,
      ];

      const translateY = scrollX.interpolate({
        inputRange,
        outputRange: [40, 10, 40],
      });

      // filterLessonsInTheParent(item)
      
      return (
        <Card
          size="large"
          style={{
            ...styles.titleCard,
            transform: [{ translateY }],
            width: ITEM_SIZE,
          }}
          key={`${item.category}-${index}`}
        >
          <Text>{item.category}</Text>
        </Card>
      );
    }

Leave a Comment