How to scroll To next item on a button click using FlatList in React Native?

Viewed 5207

I have an array of months which I am using to display months using a horizontal FlatList. I want the months to change using 2 buttons that are forward button to change the month in increasing order i.e from January to February and so on and a back button to change the month backwards i.e from January to December.

enter image description here How can I make the buttons do so. Below monthName is an array that contains all the month names.

<ScrollView style={{flexGrow: 1}}>
      <View style={{flex: 1, backgroundColor: '#fff', height: hp('130')}}>
          <View
            style={{
justifyContent: 'space-evenly',
          width: wp('48'),
        }}>
        <FlatList
          data={monthName}
          pagingEnabled={true}
          showsHorizontalScrollIndicator={false}
          renderItem={(month, index) => (
            <View>
              <Months
                showMonth={month.item}
                id={month.id}
                refer={flatRef}
              />
            </View>
          )}
          keyExtractor={(item, index) => item.id.toString()}
          horizontal
          // snapToInterval={Dimensions.get('window').width}
          snapToAlignment={'center'}
          ref={(node) => (flatRef = node)}
        />
      </View>

      <View
        style={{
          justifyContent: 'space-evenly',
          width: wp('12'),
        }}>
        {/* {} */}
        <IonIcons.Button  --> the button that makes the month increment.
          name="arrow-forward"
          size={25}
          backgroundColor="white"
          color="black"
          // onPress={() => console.log('pressed')}
          onPress={() => {
            flatRef.scrollToIndex({index: ?});
          }}
        />
      </View>
</View>

</ScrollView>
3 Answers

try to access ref using current and it should work

this.flatRef.current.scrollToIndex({index: monthName.length > this.state.currentindex ? this.state.currentindex++ : this.state.currentindex });

Instead of using a FlatList I would suggest you to make a state variable and execute it like this

Working example - Here

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { AntDesign } from '@expo/vector-icons';

...

  const [SelectMonth, SetSelectMonth] = React.useState(monthName[0]);

  const NextPress = () => {
    if (SelectMonth.id !== 12) {
      let temp = monthName.find((c) => c.id === SelectMonth.id + 1);
      if (temp) {
        SetSelectMonth(temp);
      }
    }
  };

  const PrevPress = () => {
    if (SelectMonth.id !== 1) {
      let temp = monthName.find((c) => c.id === SelectMonth.id - 1);
      if (temp) {
        SetSelectMonth(temp);
      }
    }
  };

  return (
    <View style={styles.container}>
      <View style={styles.CalenderBox}>
        <AntDesign
          name="caretleft"
          size={30}
          color="black"
          onPress={() => PrevPress()}
        />

        <View style={styles.MonthNameBox}>
          <Text style={{ fontWeight: 'bold', fontSize: 24 }}>
            {SelectMonth.name}
          </Text>
        </View>

        <AntDesign
          name="caretright"
          size={30}
          color="black"
          onPress={() => NextPress()}
        />
      </View>
    </View>
  );
import React, { useRef } from 'react';
import {
    FlatList,
    StyleSheet,
    Text,
    TouchableOpacity,
    View
} from 'react-native';
import { wp } from '../../constants/scaling';
import { colors } from '../../constants/theme';
import bookingprocess from '../../data/BookingProcess';
import { textStyles } from '../../styles/textStyles';
import { RFValue } from 'react-native-responsive-fontsize';
import AntDesign from 'react-native-vector-icons/AntDesign';

const BookingProcess = ({}) => {
    const flatListRef = useRef(FlatList);
    const nextPress = index => {
        if (index <= 2) {
            flatListRef?.current?.scrollToIndex({
                animated: true,
                index: index + 1
            });
        }
    };
    const backPress = index => {
        if (index >= 1) {
            flatListRef?.current?.scrollToIndex({
                animated: true,
                index: index - 1
            });
        }
    };
    return (
        <View
            style={{
                ...styles.cardView,
                padding: 0,
                elevation: 0,
                borderWidth: 1,
                borderColor: '#f2f2f2',
                overflow: 'hidden'
            }}>
            <View
                style={{
                    padding: wp(2),
                    backgroundColor: colors.primaryColor
                }}>
                <Text
                    style={{
                        ...textStyles.heading,
                        color: '#fff'
                    }}>
                    Booking Process
                </Text>
            </View>
            <Text
                style={{
                    ...textStyles.mediumheading,
                    padding: wp(2),
                    paddingBottom: 0
                }}>
                You can reserve your parking slot in advance. Please follow
                these four simple steps to book your parking slot.
            </Text>
            <FlatList
                data={bookingprocess}
                horizontal={true}
                ref={flatListRef}
                contentContainerStyle={{ padding: wp(2) }}
                showsHorizontalScrollIndicator={false}
                keyExtractor={(item, index) => item.id}
                renderItem={({ item, index }) => {
                    return (
                        <View style={styles.innerCard}>
                            {item.image}
                            <View style={styles.ButtonBox}>
                                <TouchableOpacity
                                    onPress={() => backPress(index)}
                                    style={{
                                        backgroundColor: colors.secondaryColor,
                                        borderRadius: wp(50)
                                    }}>
                                    <AntDesign
                                        name="leftcircle"
                                        size={RFValue(25)}
                                        color={colors.primaryColor}
                                    />
                                </TouchableOpacity>
                                <TouchableOpacity
                                    onPress={() => nextPress(index)}
                                    style={{
                                        backgroundColor: colors.secondaryColor,
                                        borderRadius: wp(50)
                                    }}>
                                    <AntDesign
                                        name="rightcircle"
                                        size={RFValue(25)}
                                        color={colors.primaryColor}
                                    />
                                </TouchableOpacity>
                            </View>
                            <View style={styles.innercardHeaderView}>
                                <Text style={styles.headingTextNumber}>
                                    {item.id}. {item.title}
                                </Text>
                            </View>

                            <Text style={styles.description}>
                                {item.description}
                            </Text>
                        </View>
                    );
                }}
            />
        </View>
    );
};

export default BookingProcess;
const styles = StyleSheet.create({
    cardView: {
        backgroundColor: colors.white,
        margin: wp(2),
        elevation: 4,
        borderRadius: wp(2),
        padding: wp(2),
        width: wp(94)
    },
    innerCard: {
        margin: wp(2),
        borderRadius: wp(2),
        padding: wp(0),
        paddingTop: 0,
        paddingHorizontal: 0,
        overflow: 'hidden',
        width: wp(90),
        elevation: 5,
        marginLeft: 0,
        padding: wp(2),
        backgroundColor: '#fff'
    },
    ButtonBox: {
        position: 'absolute',
        flexDirection: 'row',
        right: 0,
        justifyContent: 'space-between',
        width: wp(20),
        padding: wp(2)
    },
    innercardHeaderView: {
        backgroundColor: '#0000',
        flexDirection: 'row',
        padding: wp(2),
        paddingBottom: 0,
        alignItems: 'center'
    },
    headingTextNumber: {
        ...textStyles.heading,
        color: colors.primaryColor,
        textAlign: 'center',
        alignSelf: 'center',
        textAlignVertical: 'center'
    },
    description: {
        ...textStyles.mediumheading,
        paddingHorizontal: wp(2),
        textAlign: 'justify'
    }
});
Related